{
  "openapi": "3.1.0",
  "info": {
    "title": "FYLR API",
    "version": "1.0.0",
    "description": "HTTP/JSON API for **fylr**. Most endpoints below live under the\n**`/api/v1`** base path — for example `/api/v1/collection`,\n`/api/v1/search`. The OAuth2 / OpenID Connect endpoints under\n`/api/oauth2` and the discovery document at\n`/.well-known/openid-configuration` are the exceptions; each\noperation lists its own full path.\n\n**Authentication.** Calls are authenticated with an access token.\nPresent it as an `Authorization: Bearer \u003ctoken\u003e` header, or — as\nfallbacks — the `access_token` query parameter or an\n`X-Fylr-Authorization: Bearer \u003ctoken\u003e` header (a workaround for\nSafari, which overwrites `Authorization`). Tokens are issued by the\nOAuth2 token endpoint (`POST /api/oauth2/token`; the default grant\nis the resource-owner password grant). These transports are\ndeclared as the security schemes of this document. A request\nwithout a valid token runs as an anonymous session; endpoints that\nrequire a user then answer `401`.\n\n**Caching.** Responses default to `Cache-Control: no-store,\nno-cache` — most carry data specific to the authenticated user,\nand the default keeps any browser, shared proxy or CDN from\nstoring and replaying them. On any `GET` request the\n`cache_seconds` query parameter opts into caching: a value greater\nthan `0` replaces the default with\n`Cache-Control: max-age=\u003ccache_seconds\u003e, public`. Endpoints whose\ncontent is safe to cache (file downloads, IIIF tiles) set their\nown `Cache-Control` header instead.\n"
  },
  "servers": [
    {
      "url": "/api/v1"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    },
    {
      "AccessTokenQuery": []
    },
    {
      "FylrAuthHeader": []
    }
  ],
  "tags": [
    {
      "name": "config"
    },
    {
      "name": "tags"
    }
  ],
  "x-hideTryItPanel": true,
  "x-codeSamples": false,
  "paths": {
    "/collection": {
      "description": "Collections can store links to objects. It is possible to link other objects\nfrom **fylr** as well as foreign objects, unknown to **fylr**. Object links must be unique.\nLinked objects can be manually sorted.\n",
      "put": {
        "summary": "Create or update a collection.",
        "description": "* The user needs `BAG_CREATE` in the parent collection to create a collection.\n* The user needs `BAG_WRITE` to update a collection.\n* The `_owner` is set to the owner of the parent.\n* To set `_private_acl` or `_acl` the user needs `BAG_ACL`.\n* New ACL items with `send_email_notification` will sent out and email.\n* Adding or editing a shared right is validated against the owner's grantable rights; a share the owner cannot grant returns `202` (see below) unless `allow_invalid_acl=true`.\n* An update is performed if the payload contains a `_version` greater 1.\n* Moving a collection to a new parent requires `BAG_CREATE` in the new parent and `BAG_ACL` in the current collection.\n  When moving a collection, the owner is automatically set to the owner of the parent. This includes all child collections.\n* `COLLECTION_INSERT` / `COLLECTION_UPDATE` event is written.\n\nDiffers from easydb 5: the `children_allowed` flag is stored but has no\neffect. easydb 5 enforces it, rejecting an attempt \"to create or move a\ncollection under a collection that does not allow children\" with the\n`Collection Does Not Allow Children` error; **fylr** raises no such error.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "Allow storing the collection even if the owner doesn't have the necessary\npermissions for all objects to share the rights defined in the `_acl` property\nof the collection. The `_invalid_acl` flag will be set, if the user doesn't\nhave sufficient permissions to share all objects of the collection. The user\nneeds the permission `BAG_ACL` for the collection in order to use this\nparameter.\n\nDiffers from easydb 5: this confirmation is driven by the boolean\n`allow_invalid_acl` parameter. easydb 5 instead resolves the `202`\nconfirmation with a `collection_rights_policy` query parameter; there is no\n`allow_invalid_acl` parameter in easydb 5.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, the invalid-ACL validity check (whether the collection owner may\ngrant the rights of all linked objects) is not run inline. Instead a queued\n`ACTION_COLLECTION_ACL_CHECK` job is scheduled and the request returns\nimmediately, before the check has resolved.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "collection": {
                    "type": "object",
                    "properties": {
                      "_id": {
                        "type": "number",
                        "format": "int64",
                        "minimum": 1,
                        "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                      },
                      "_id_parent": {
                        "type": "number",
                        "format": "int64",
                        "minimum": 1,
                        "nullable": true,
                        "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                      },
                      "_version": {
                        "type": "number",
                        "format": "int64",
                        "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                      },
                      "children_allowed": {
                        "type": "boolean",
                        "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                      },
                      "objects_allowed": {
                        "type": "boolean",
                        "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                      },
                      "is_system_collection": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                      },
                      "webfrontend_props": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                      },
                      "displayname": {
                        "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                        "type": "object",
                        "properties": {
                          "de-DE": {
                            "type": "string"
                          },
                          "en-US": {
                            "type": "string"
                          }
                        },
                        "example": {
                          "de-DE": "Deutscher text",
                          "en-US": "English text"
                        }
                      },
                      "description": {
                        "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                        "type": "object",
                        "properties": {
                          "de-DE": {
                            "type": "string"
                          },
                          "en-US": {
                            "type": "string"
                          }
                        },
                        "example": {
                          "de-DE": "Deutscher text",
                          "en-US": "English text"
                        }
                      },
                      "create_object": {
                        "nullable": true,
                        "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                        "type": "object",
                        "properties": {
                          "objecttype": {
                            "type": "string",
                            "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                          },
                          "mask_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                          },
                          "pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                          },
                          "linked_pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                          },
                          "pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                          },
                          "linked_pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                          },
                          "eas_field": {
                            "type": "string",
                            "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                          },
                          "linked_object_pools": {
                            "type": "object",
                            "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "hierarchy_linked_object": {
                            "type": "object",
                            "nullable": true,
                            "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                            "properties": {
                              "field": {
                                "type": "string",
                                "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                              }
                            }
                          },
                          "mapping": {
                            "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                            "oneOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "standard",
                                  "none"
                                ]
                              },
                              {
                                "type": "integer",
                                "format": "int64"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "mapping_recipe_configs": {
                            "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                            "allOf": [
                              {
                                "type": "object",
                                "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                  "properties": {
                                    "params": {
                                      "type": "object",
                                      "additionalProperties": true,
                                      "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                      "example": {
                                        "size": 600,
                                        "format": "png",
                                        "resize_mode": "max",
                                        "jpegquality": 80,
                                        "strip": true
                                      }
                                    }
                                  },
                                  "example": {
                                    "imageconverter:browserthumbs": {
                                      "params": {
                                        "size": 1200,
                                        "format": "webp",
                                        "resize_mode": "max"
                                      }
                                    },
                                    "imageconverter:preview_pool_watermark": {
                                      "params": {
                                        "size": 600,
                                        "format": "jpg"
                                      }
                                    }
                                  }
                                }
                              }
                            ]
                          },
                          "recognize_series": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                          },
                          "recognize_version": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                          },
                          "update_search_field": {
                            "type": "string",
                            "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                          },
                          "update_mode": {
                            "type": "string",
                            "default": "insert",
                            "enum": [
                              "insert",
                              "update",
                              "upsert"
                            ],
                            "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                          },
                          "update_policy": {
                            "type": "string",
                            "enum": [
                              "create_version",
                              "replace",
                              "create_version_preferred",
                              "refuse"
                            ],
                            "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                          },
                          "tags": {
                            "type": "array",
                            "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                            "items": {
                              "$ref": "#/components/schemas/Tag"
                            }
                          },
                          "plugin": {
                            "type": "string",
                            "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                            "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                          },
                          "plugin_config": {
                            "type": "object",
                            "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          }
                        }
                      },
                      "reference": {
                        "type": "string",
                        "nullable": true,
                        "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                      },
                      "shortname": {
                        "type": "string",
                        "nullable": true,
                        "description": "A unique string to set a collection shortname. This can be used for search.\n"
                      },
                      "type": {
                        "type": "string",
                        "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                      },
                      "pin_code": {
                        "type": "string",
                        "nullable": true,
                        "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                      },
                      "uuid": {
                        "type": "string",
                        "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                      },
                      "lookup:_id": {
                        "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                        "type": "object",
                        "properties": {
                          "reference": {
                            "type": "string",
                            "description": "The reference of the collection to lookup.\n"
                          }
                        }
                      },
                      "lookup:_id_parent": {
                        "description": "The lookup to find the parent collection.\n",
                        "type": "object",
                        "properties": {
                          "reference": {
                            "type": "string",
                            "description": "The reference of the collection to lookup.\n"
                          }
                        }
                      }
                    }
                  },
                  "_basetype": {
                    "type": "string",
                    "enum": [
                      "collection"
                    ]
                  },
                  "_count": {
                    "type": "number",
                    "format": "int64",
                    "readOnly": true,
                    "description": "The number of objects in this collection.\n"
                  },
                  "_count_recursive": {
                    "type": "number",
                    "format": "int64",
                    "readOnly": true,
                    "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                  },
                  "_create_object_compiled": {
                    "readOnly": true,
                    "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                    "type": "object",
                    "properties": {
                      "objecttype": {
                        "type": "string",
                        "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                      },
                      "mask_id": {
                        "type": "integer",
                        "format": "int64",
                        "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                      },
                      "pool_id": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                      },
                      "linked_pool_id": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                      },
                      "pool": {
                        "$ref": "#/components/schemas/PoolApi",
                        "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                      },
                      "linked_pool": {
                        "$ref": "#/components/schemas/PoolApi",
                        "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                      },
                      "eas_field": {
                        "type": "string",
                        "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                      },
                      "linked_object_pools": {
                        "type": "object",
                        "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                        "additionalProperties": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      },
                      "hierarchy_linked_object": {
                        "type": "object",
                        "nullable": true,
                        "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                        "properties": {
                          "field": {
                            "type": "string",
                            "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                          }
                        }
                      },
                      "mapping": {
                        "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                        "oneOf": [
                          {
                            "type": "string",
                            "enum": [
                              "standard",
                              "none"
                            ]
                          },
                          {
                            "type": "integer",
                            "format": "int64"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "mapping_recipe_configs": {
                        "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                        "allOf": [
                          {
                            "type": "object",
                            "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                            "additionalProperties": {
                              "type": "object",
                              "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                              "properties": {
                                "params": {
                                  "type": "object",
                                  "additionalProperties": true,
                                  "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                  "example": {
                                    "size": 600,
                                    "format": "png",
                                    "resize_mode": "max",
                                    "jpegquality": 80,
                                    "strip": true
                                  }
                                }
                              },
                              "example": {
                                "imageconverter:browserthumbs": {
                                  "params": {
                                    "size": 1200,
                                    "format": "webp",
                                    "resize_mode": "max"
                                  }
                                },
                                "imageconverter:preview_pool_watermark": {
                                  "params": {
                                    "size": 600,
                                    "format": "jpg"
                                  }
                                }
                              }
                            }
                          }
                        ]
                      },
                      "recognize_series": {
                        "type": "boolean",
                        "default": false,
                        "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                      },
                      "recognize_version": {
                        "type": "boolean",
                        "default": false,
                        "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                      },
                      "update_search_field": {
                        "type": "string",
                        "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                      },
                      "update_mode": {
                        "type": "string",
                        "default": "insert",
                        "enum": [
                          "insert",
                          "update",
                          "upsert"
                        ],
                        "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                      },
                      "update_policy": {
                        "type": "string",
                        "enum": [
                          "create_version",
                          "replace",
                          "create_version_preferred",
                          "refuse"
                        ],
                        "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                      },
                      "tags": {
                        "type": "array",
                        "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                        "items": {
                          "$ref": "#/components/schemas/Tag"
                        }
                      },
                      "plugin": {
                        "type": "string",
                        "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                        "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                      },
                      "plugin_config": {
                        "type": "object",
                        "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                        "additionalProperties": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      }
                    }
                  },
                  "_generated_rights": {
                    "type": "object",
                    "readOnly": true,
                    "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                    "properties": {
                      "create": {
                        "type": "object",
                        "properties": {}
                      },
                      "create_in_collection": {
                        "type": "object",
                        "properties": {}
                      },
                      "read": {
                        "type": "object",
                        "properties": {}
                      },
                      "write": {
                        "type": "object",
                        "properties": {}
                      },
                      "delete": {
                        "type": "object",
                        "properties": {}
                      },
                      "asset_upload": {
                        "type": "object",
                        "properties": {}
                      },
                      "asset_show": {
                        "type": "object",
                        "properties": {}
                      },
                      "asset_download": {
                        "type": "object",
                        "properties": {}
                      },
                      "mask": {
                        "type": "object",
                        "properties": {}
                      },
                      "link": {
                        "type": "object",
                        "properties": {}
                      },
                      "acl": {
                        "type": "object",
                        "properties": {}
                      },
                      "change_owner": {
                        "type": "object",
                        "properties": {}
                      },
                      "unlink": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_read": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_write": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_acl": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_delete": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_create": {
                        "type": "object",
                        "properties": {}
                      },
                      "owner": {
                        "type": "object",
                        "properties": {}
                      }
                    }
                  },
                  "_has_acl": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                  },
                  "_has_children": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                  },
                  "_has_remote_objects": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                  },
                  "_level": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                  },
                  "_acl": {
                    "type": "array",
                    "items": {
                      "description": "List of permissions.",
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                        },
                        "who": {
                          "type": "object",
                          "properties": {
                            "_basetype": {
                              "type": "string",
                              "enum": [
                                "user",
                                "group"
                              ]
                            },
                            "_owner": {
                              "type": "boolean",
                              "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                            },
                            "_pool_contact": {
                              "type": "boolean",
                              "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                            },
                            "user": {
                              "type": "object",
                              "properties": {
                                "_id": {
                                  "type": "number",
                                  "format": "int64",
                                  "description": "The id of the user.\n"
                                },
                                "_version": {
                                  "type": "number",
                                  "readOnly": true,
                                  "format": "int64",
                                  "description": "The version of the user record.\n"
                                },
                                "type": {
                                  "type": "string",
                                  "readOnly": true,
                                  "enum": [
                                    "system",
                                    "easydb",
                                    "easydb_self_register",
                                    "anonymous",
                                    "collection",
                                    "email",
                                    "ldap",
                                    "sso"
                                  ]
                                },
                                "_generated_displayname": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                },
                                "login": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "Set for users of type `collection` or `email`.\n"
                                },
                                "frontend_language": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "The preferred frontend language of the user (BCP 47)\n"
                                }
                              }
                            },
                            "group": {
                              "type": "object",
                              "properties": {
                                "_id": {
                                  "type": "number",
                                  "format": "int64",
                                  "description": "The id of the group.\n"
                                },
                                "_generated_displayname": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                }
                              }
                            }
                          }
                        },
                        "sticky": {
                          "type": "boolean",
                          "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                        },
                        "active": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                        },
                        "_right_preset": {
                          "type": "number",
                          "format": "int64",
                          "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                        },
                        "when": {
                          "type": "object",
                          "properties": {
                            "from": {
                              "type": "string",
                              "format": "iso8601_date",
                              "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                            },
                            "to": {
                              "type": "string",
                              "format": "iso8601_date"
                            }
                          }
                        },
                        "rights": {
                          "description": "Object which carries the permissions granted by this item.\n",
                          "type": "object",
                          "additionalProperties": {
                            "type": "object",
                            "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                            "properties": {
                              "_grantable": {
                                "type": "boolean",
                                "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                              },
                              "allow_update_and_remove": {
                                "type": "boolean",
                                "description": "Flag to allow to update or remove a file id from a column.\n"
                              },
                              "classes": {
                                "type": "array",
                                "description": "List of classes this permission if given for. An empty list matches all.\n",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "extensions": {
                                "type": "array",
                                "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "versions": {
                                "type": "array",
                                "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "limit": {
                                "type": "string",
                                "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                              },
                              "mask_ids": {
                                "type": "object",
                                "additionalProperties": {
                                  "description": "The key is the object type ID.\n",
                                  "type": "array",
                                  "items": {
                                    "oneOf": [
                                      {
                                        "type": "string",
                                        "description": "Set to `standard` for the standard mask.\n",
                                        "enum": [
                                          "standard"
                                        ]
                                      },
                                      {
                                        "type": "integer",
                                        "description": "The mask id given the permission for.\n",
                                        "minimum": 1
                                      }
                                    ]
                                  }
                                }
                              },
                              "column_ids": {
                                "description": "List of column api ids to apply this permission to.\n",
                                "type": "array",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "objecttype_ids": {
                                "description": "List of object type ids to apply this permission to.\n",
                                "type": "array",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "pool_ids": {
                                "description": "List of pool IDs to apply this permission to.\n",
                                "type": "array",
                                "items": {
                                  "type": "integer"
                                }
                              }
                            }
                          }
                        },
                        "tagfilter": {
                          "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                          "type": "object",
                          "properties": {
                            "any": {
                              "type": "array",
                              "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                              "items": {
                                "type": "integer"
                              }
                            },
                            "all": {
                              "type": "array",
                              "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                              "items": {
                                "type": "integer"
                              }
                            },
                            "not": {
                              "type": "array",
                              "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                              "items": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "send_email_notification": {
                          "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                          "type": "object",
                          "properties": {
                            "text": {
                              "description": "The text included in the email.\n",
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "_private_acl": {
                    "type": "boolean",
                    "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                  },
                  "_path": {
                    "type": "array",
                    "readOnly": true,
                    "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                    "items": {
                      "type": "object",
                      "properties": {
                        "_basetype": {
                          "type": "string",
                          "enum": [
                            "collection"
                          ]
                        },
                        "collection": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "integer"
                            },
                            "_id_parent": {
                              "type": "integer"
                            },
                            "_version": {
                              "type": "integer"
                            },
                            "displayname": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "_invalid_acl": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                  },
                  "_owner": {
                    "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                    "type": "object",
                    "properties": {
                      "_basetype": {
                        "type": "string",
                        "enum": [
                          "user",
                          "group"
                        ]
                      },
                      "_owner": {
                        "type": "boolean",
                        "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                      },
                      "_pool_contact": {
                        "type": "boolean",
                        "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                      },
                      "user": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "The id of the user.\n"
                          },
                          "_version": {
                            "type": "number",
                            "readOnly": true,
                            "format": "int64",
                            "description": "The version of the user record.\n"
                          },
                          "type": {
                            "type": "string",
                            "readOnly": true,
                            "enum": [
                              "system",
                              "easydb",
                              "easydb_self_register",
                              "anonymous",
                              "collection",
                              "email",
                              "ldap",
                              "sso"
                            ]
                          },
                          "_generated_displayname": {
                            "type": "string",
                            "readOnly": true,
                            "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                          },
                          "login": {
                            "type": "string",
                            "readOnly": true,
                            "description": "Set for users of type `collection` or `email`.\n"
                          },
                          "frontend_language": {
                            "type": "string",
                            "readOnly": true,
                            "description": "The preferred frontend language of the user (BCP 47)\n"
                          }
                        }
                      },
                      "group": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "The id of the group.\n"
                          },
                          "_generated_displayname": {
                            "type": "string",
                            "readOnly": true,
                            "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                          }
                        }
                      }
                    }
                  },
                  "objects": {
                    "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "_global_object_id": {
                          "type": "string",
                          "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "lookup:_global_object_id": {
                          "type": "object",
                          "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                          "properties": {
                            "_allow_defer": {
                              "type": "boolean"
                            },
                            "_objecttype": {
                              "type": "string"
                            },
                            "_system_object_id": {
                              "type": "integer"
                            },
                            "_uuid": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "_hotfolder_upload_urls": {
                    "description": "A list of URLs to upload files into this collection.\n",
                    "type": "array",
                    "readOnly": true,
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                          "type": "string",
                          "enum": [
                            "webdav",
                            "webdav-hotfolder"
                          ]
                        },
                        "url": {
                          "type": "string",
                          "format": "url"
                        }
                      }
                    }
                  },
                  "_has_pin": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                  },
                  "pin_ok": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                  },
                  "_created_at": {
                    "type": "string",
                    "format": "RFC3339_date",
                    "readOnly": true,
                    "description": "Timestamp when this collection was created.\n"
                  },
                  "_updated_at": {
                    "type": "string",
                    "format": "RFC3339_date",
                    "readOnly": true,
                    "description": "Timestamp when this collection was updated.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The response contains the collection created, including the issued `_id`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "collection": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                        },
                        "_id_parent": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "nullable": true,
                          "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                        },
                        "_version": {
                          "type": "number",
                          "format": "int64",
                          "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                        },
                        "children_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                        },
                        "objects_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                        },
                        "is_system_collection": {
                          "type": "boolean",
                          "readOnly": true,
                          "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "displayname": {
                          "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "description": {
                          "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "create_object": {
                          "nullable": true,
                          "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                          "type": "object",
                          "properties": {
                            "objecttype": {
                              "type": "string",
                              "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                            },
                            "mask_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                            },
                            "pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                            },
                            "linked_pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                            },
                            "pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                            },
                            "linked_pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                            },
                            "eas_field": {
                              "type": "string",
                              "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                            },
                            "linked_object_pools": {
                              "type": "object",
                              "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            },
                            "hierarchy_linked_object": {
                              "type": "object",
                              "nullable": true,
                              "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                                }
                              }
                            },
                            "mapping": {
                              "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                              "oneOf": [
                                {
                                  "type": "string",
                                  "enum": [
                                    "standard",
                                    "none"
                                  ]
                                },
                                {
                                  "type": "integer",
                                  "format": "int64"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "mapping_recipe_configs": {
                              "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                              "allOf": [
                                {
                                  "type": "object",
                                  "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                  "additionalProperties": {
                                    "type": "object",
                                    "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                    "properties": {
                                      "params": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                        "example": {
                                          "size": 600,
                                          "format": "png",
                                          "resize_mode": "max",
                                          "jpegquality": 80,
                                          "strip": true
                                        }
                                      }
                                    },
                                    "example": {
                                      "imageconverter:browserthumbs": {
                                        "params": {
                                          "size": 1200,
                                          "format": "webp",
                                          "resize_mode": "max"
                                        }
                                      },
                                      "imageconverter:preview_pool_watermark": {
                                        "params": {
                                          "size": 600,
                                          "format": "jpg"
                                        }
                                      }
                                    }
                                  }
                                }
                              ]
                            },
                            "recognize_series": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                            },
                            "recognize_version": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                            },
                            "update_search_field": {
                              "type": "string",
                              "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                            },
                            "update_mode": {
                              "type": "string",
                              "default": "insert",
                              "enum": [
                                "insert",
                                "update",
                                "upsert"
                              ],
                              "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                            },
                            "update_policy": {
                              "type": "string",
                              "enum": [
                                "create_version",
                                "replace",
                                "create_version_preferred",
                                "refuse"
                              ],
                              "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                            },
                            "tags": {
                              "type": "array",
                              "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                              "items": {
                                "$ref": "#/components/schemas/Tag"
                              }
                            },
                            "plugin": {
                              "type": "string",
                              "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                              "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                            },
                            "plugin_config": {
                              "type": "object",
                              "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            }
                          }
                        },
                        "reference": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                        },
                        "shortname": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection shortname. This can be used for search.\n"
                        },
                        "type": {
                          "type": "string",
                          "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                        },
                        "pin_code": {
                          "type": "string",
                          "nullable": true,
                          "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                        },
                        "uuid": {
                          "type": "string",
                          "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                        },
                        "lookup:_id": {
                          "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        },
                        "lookup:_id_parent": {
                          "description": "The lookup to find the parent collection.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        }
                      }
                    },
                    "_basetype": {
                      "type": "string",
                      "enum": [
                        "collection"
                      ]
                    },
                    "_count": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection.\n"
                    },
                    "_count_recursive": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                    },
                    "_create_object_compiled": {
                      "readOnly": true,
                      "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                      "type": "object",
                      "properties": {
                        "objecttype": {
                          "type": "string",
                          "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                        },
                        "mask_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                        },
                        "pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                        },
                        "linked_pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                        },
                        "pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                        },
                        "linked_pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                        },
                        "eas_field": {
                          "type": "string",
                          "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                        },
                        "linked_object_pools": {
                          "type": "object",
                          "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "hierarchy_linked_object": {
                          "type": "object",
                          "nullable": true,
                          "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                          "properties": {
                            "field": {
                              "type": "string",
                              "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                            }
                          }
                        },
                        "mapping": {
                          "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                          "oneOf": [
                            {
                              "type": "string",
                              "enum": [
                                "standard",
                                "none"
                              ]
                            },
                            {
                              "type": "integer",
                              "format": "int64"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mapping_recipe_configs": {
                          "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                          "allOf": [
                            {
                              "type": "object",
                              "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                              "additionalProperties": {
                                "type": "object",
                                "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                "properties": {
                                  "params": {
                                    "type": "object",
                                    "additionalProperties": true,
                                    "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                    "example": {
                                      "size": 600,
                                      "format": "png",
                                      "resize_mode": "max",
                                      "jpegquality": 80,
                                      "strip": true
                                    }
                                  }
                                },
                                "example": {
                                  "imageconverter:browserthumbs": {
                                    "params": {
                                      "size": 1200,
                                      "format": "webp",
                                      "resize_mode": "max"
                                    }
                                  },
                                  "imageconverter:preview_pool_watermark": {
                                    "params": {
                                      "size": 600,
                                      "format": "jpg"
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        },
                        "recognize_series": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                        },
                        "recognize_version": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                        },
                        "update_search_field": {
                          "type": "string",
                          "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                        },
                        "update_mode": {
                          "type": "string",
                          "default": "insert",
                          "enum": [
                            "insert",
                            "update",
                            "upsert"
                          ],
                          "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                        },
                        "update_policy": {
                          "type": "string",
                          "enum": [
                            "create_version",
                            "replace",
                            "create_version_preferred",
                            "refuse"
                          ],
                          "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                        },
                        "tags": {
                          "type": "array",
                          "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                          "items": {
                            "$ref": "#/components/schemas/Tag"
                          }
                        },
                        "plugin": {
                          "type": "string",
                          "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                          "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                        },
                        "plugin_config": {
                          "type": "object",
                          "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        }
                      }
                    },
                    "_generated_rights": {
                      "type": "object",
                      "readOnly": true,
                      "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                      "properties": {
                        "create": {
                          "type": "object",
                          "properties": {}
                        },
                        "create_in_collection": {
                          "type": "object",
                          "properties": {}
                        },
                        "read": {
                          "type": "object",
                          "properties": {}
                        },
                        "write": {
                          "type": "object",
                          "properties": {}
                        },
                        "delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_upload": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_show": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_download": {
                          "type": "object",
                          "properties": {}
                        },
                        "mask": {
                          "type": "object",
                          "properties": {}
                        },
                        "link": {
                          "type": "object",
                          "properties": {}
                        },
                        "acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "change_owner": {
                          "type": "object",
                          "properties": {}
                        },
                        "unlink": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_read": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_write": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_create": {
                          "type": "object",
                          "properties": {}
                        },
                        "owner": {
                          "type": "object",
                          "properties": {}
                        }
                      }
                    },
                    "_has_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                    },
                    "_has_children": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                    },
                    "_has_remote_objects": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                    },
                    "_level": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                    },
                    "_acl": {
                      "type": "array",
                      "items": {
                        "description": "List of permissions.",
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                          },
                          "who": {
                            "type": "object",
                            "properties": {
                              "_basetype": {
                                "type": "string",
                                "enum": [
                                  "user",
                                  "group"
                                ]
                              },
                              "_owner": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                              },
                              "_pool_contact": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                              },
                              "user": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the user.\n"
                                  },
                                  "_version": {
                                    "type": "number",
                                    "readOnly": true,
                                    "format": "int64",
                                    "description": "The version of the user record.\n"
                                  },
                                  "type": {
                                    "type": "string",
                                    "readOnly": true,
                                    "enum": [
                                      "system",
                                      "easydb",
                                      "easydb_self_register",
                                      "anonymous",
                                      "collection",
                                      "email",
                                      "ldap",
                                      "sso"
                                    ]
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                  },
                                  "login": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "Set for users of type `collection` or `email`.\n"
                                  },
                                  "frontend_language": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "The preferred frontend language of the user (BCP 47)\n"
                                  }
                                }
                              },
                              "group": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the group.\n"
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                  }
                                }
                              }
                            }
                          },
                          "sticky": {
                            "type": "boolean",
                            "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                          },
                          "active": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                          },
                          "_right_preset": {
                            "type": "number",
                            "format": "int64",
                            "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                          },
                          "when": {
                            "type": "object",
                            "properties": {
                              "from": {
                                "type": "string",
                                "format": "iso8601_date",
                                "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                              },
                              "to": {
                                "type": "string",
                                "format": "iso8601_date"
                              }
                            }
                          },
                          "rights": {
                            "description": "Object which carries the permissions granted by this item.\n",
                            "type": "object",
                            "additionalProperties": {
                              "type": "object",
                              "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                              "properties": {
                                "_grantable": {
                                  "type": "boolean",
                                  "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                                },
                                "allow_update_and_remove": {
                                  "type": "boolean",
                                  "description": "Flag to allow to update or remove a file id from a column.\n"
                                },
                                "classes": {
                                  "type": "array",
                                  "description": "List of classes this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "extensions": {
                                  "type": "array",
                                  "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "versions": {
                                  "type": "array",
                                  "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "limit": {
                                  "type": "string",
                                  "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                                },
                                "mask_ids": {
                                  "type": "object",
                                  "additionalProperties": {
                                    "description": "The key is the object type ID.\n",
                                    "type": "array",
                                    "items": {
                                      "oneOf": [
                                        {
                                          "type": "string",
                                          "description": "Set to `standard` for the standard mask.\n",
                                          "enum": [
                                            "standard"
                                          ]
                                        },
                                        {
                                          "type": "integer",
                                          "description": "The mask id given the permission for.\n",
                                          "minimum": 1
                                        }
                                      ]
                                    }
                                  }
                                },
                                "column_ids": {
                                  "description": "List of column api ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "objecttype_ids": {
                                  "description": "List of object type ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "pool_ids": {
                                  "description": "List of pool IDs to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                }
                              }
                            }
                          },
                          "tagfilter": {
                            "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                            "type": "object",
                            "properties": {
                              "any": {
                                "type": "array",
                                "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "all": {
                                "type": "array",
                                "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "not": {
                                "type": "array",
                                "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              }
                            }
                          },
                          "send_email_notification": {
                            "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                            "type": "object",
                            "properties": {
                              "text": {
                                "description": "The text included in the email.\n",
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_private_acl": {
                      "type": "boolean",
                      "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                    },
                    "_path": {
                      "type": "array",
                      "readOnly": true,
                      "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_basetype": {
                            "type": "string",
                            "enum": [
                              "collection"
                            ]
                          },
                          "collection": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "integer"
                              },
                              "_id_parent": {
                                "type": "integer"
                              },
                              "_version": {
                                "type": "integer"
                              },
                              "displayname": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_invalid_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                    },
                    "_owner": {
                      "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                      "type": "object",
                      "properties": {
                        "_basetype": {
                          "type": "string",
                          "enum": [
                            "user",
                            "group"
                          ]
                        },
                        "_owner": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                        },
                        "_pool_contact": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                        },
                        "user": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the user.\n"
                            },
                            "_version": {
                              "type": "number",
                              "readOnly": true,
                              "format": "int64",
                              "description": "The version of the user record.\n"
                            },
                            "type": {
                              "type": "string",
                              "readOnly": true,
                              "enum": [
                                "system",
                                "easydb",
                                "easydb_self_register",
                                "anonymous",
                                "collection",
                                "email",
                                "ldap",
                                "sso"
                              ]
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                            },
                            "login": {
                              "type": "string",
                              "readOnly": true,
                              "description": "Set for users of type `collection` or `email`.\n"
                            },
                            "frontend_language": {
                              "type": "string",
                              "readOnly": true,
                              "description": "The preferred frontend language of the user (BCP 47)\n"
                            }
                          }
                        },
                        "group": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the group.\n"
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                            }
                          }
                        }
                      }
                    },
                    "objects": {
                      "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_global_object_id": {
                            "type": "string",
                            "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                          },
                          "webfrontend_props": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                          },
                          "lookup:_global_object_id": {
                            "type": "object",
                            "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                            "properties": {
                              "_allow_defer": {
                                "type": "boolean"
                              },
                              "_objecttype": {
                                "type": "string"
                              },
                              "_system_object_id": {
                                "type": "integer"
                              },
                              "_uuid": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_hotfolder_upload_urls": {
                      "description": "A list of URLs to upload files into this collection.\n",
                      "type": "array",
                      "readOnly": true,
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                            "type": "string",
                            "enum": [
                              "webdav",
                              "webdav-hotfolder"
                            ]
                          },
                          "url": {
                            "type": "string",
                            "format": "url"
                          }
                        }
                      }
                    },
                    "_has_pin": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                    },
                    "pin_ok": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                    },
                    "_created_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was created.\n"
                    },
                    "_updated_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was updated.\n"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The collection owner cannot grant one of the collection's shared\nrights for an object it contains — whether a share was added, an\nexisting share's rights were edited, or an object was added — and the\ncaller has `BAG_ACL`. The check runs on every save endpoint. Re-send\nwith `allow_invalid_acl=true` to store the collection with sharing\ndisabled.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the\nresponse identifies which validation rejected the request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionRemoveNotAllObjectsFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required `BAG_*` permission on the\ncollection (or a required system right). See `code` for the\nspecific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create or update a collection.",
        "description": "* The user needs `BAG_CREATE` in the parent collection to create a collection.\n* The user needs `BAG_WRITE` to update a collection.\n* The `_owner` is set to the owner of the parent.\n* To set `_private_acl` or `_acl` the user needs `BAG_ACL`.\n* New ACL items with `send_email_notification` will sent out and email.\n* Adding or editing a shared right is validated against the owner's grantable rights; a share the owner cannot grant returns `202` (see below) unless `allow_invalid_acl=true`.\n* An update is performed if the payload contains a `_version` greater 1.\n* Moving a collection to a new parent requires `BAG_CREATE` in the new parent and `BAG_ACL` in the current collection.\n  When moving a collection, the owner is automatically set to the owner of the parent. This includes all child collections.\n* `COLLECTION_INSERT` / `COLLECTION_UPDATE` event is written.\n\nDiffers from easydb 5: the `children_allowed` flag is stored but has no\neffect. easydb 5 enforces it, rejecting an attempt \"to create or move a\ncollection under a collection that does not allow children\" with the\n`Collection Does Not Allow Children` error; **fylr** raises no such error.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "Allow storing the collection even if the owner doesn't have the necessary\npermissions for all objects to share the rights defined in the `_acl` property\nof the collection. The `_invalid_acl` flag will be set, if the user doesn't\nhave sufficient permissions to share all objects of the collection. The user\nneeds the permission `BAG_ACL` for the collection in order to use this\nparameter.\n\nDiffers from easydb 5: this confirmation is driven by the boolean\n`allow_invalid_acl` parameter. easydb 5 instead resolves the `202`\nconfirmation with a `collection_rights_policy` query parameter; there is no\n`allow_invalid_acl` parameter in easydb 5.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, the invalid-ACL validity check (whether the collection owner may\ngrant the rights of all linked objects) is not run inline. Instead a queued\n`ACTION_COLLECTION_ACL_CHECK` job is scheduled and the request returns\nimmediately, before the check has resolved.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "collection": {
                    "type": "object",
                    "properties": {
                      "_id": {
                        "type": "number",
                        "format": "int64",
                        "minimum": 1,
                        "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                      },
                      "_id_parent": {
                        "type": "number",
                        "format": "int64",
                        "minimum": 1,
                        "nullable": true,
                        "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                      },
                      "_version": {
                        "type": "number",
                        "format": "int64",
                        "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                      },
                      "children_allowed": {
                        "type": "boolean",
                        "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                      },
                      "objects_allowed": {
                        "type": "boolean",
                        "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                      },
                      "is_system_collection": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                      },
                      "webfrontend_props": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                      },
                      "displayname": {
                        "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                        "type": "object",
                        "properties": {
                          "de-DE": {
                            "type": "string"
                          },
                          "en-US": {
                            "type": "string"
                          }
                        },
                        "example": {
                          "de-DE": "Deutscher text",
                          "en-US": "English text"
                        }
                      },
                      "description": {
                        "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                        "type": "object",
                        "properties": {
                          "de-DE": {
                            "type": "string"
                          },
                          "en-US": {
                            "type": "string"
                          }
                        },
                        "example": {
                          "de-DE": "Deutscher text",
                          "en-US": "English text"
                        }
                      },
                      "create_object": {
                        "nullable": true,
                        "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                        "type": "object",
                        "properties": {
                          "objecttype": {
                            "type": "string",
                            "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                          },
                          "mask_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                          },
                          "pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                          },
                          "linked_pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                          },
                          "pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                          },
                          "linked_pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                          },
                          "eas_field": {
                            "type": "string",
                            "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                          },
                          "linked_object_pools": {
                            "type": "object",
                            "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "hierarchy_linked_object": {
                            "type": "object",
                            "nullable": true,
                            "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                            "properties": {
                              "field": {
                                "type": "string",
                                "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                              }
                            }
                          },
                          "mapping": {
                            "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                            "oneOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "standard",
                                  "none"
                                ]
                              },
                              {
                                "type": "integer",
                                "format": "int64"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "mapping_recipe_configs": {
                            "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                            "allOf": [
                              {
                                "type": "object",
                                "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                  "properties": {
                                    "params": {
                                      "type": "object",
                                      "additionalProperties": true,
                                      "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                      "example": {
                                        "size": 600,
                                        "format": "png",
                                        "resize_mode": "max",
                                        "jpegquality": 80,
                                        "strip": true
                                      }
                                    }
                                  },
                                  "example": {
                                    "imageconverter:browserthumbs": {
                                      "params": {
                                        "size": 1200,
                                        "format": "webp",
                                        "resize_mode": "max"
                                      }
                                    },
                                    "imageconverter:preview_pool_watermark": {
                                      "params": {
                                        "size": 600,
                                        "format": "jpg"
                                      }
                                    }
                                  }
                                }
                              }
                            ]
                          },
                          "recognize_series": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                          },
                          "recognize_version": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                          },
                          "update_search_field": {
                            "type": "string",
                            "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                          },
                          "update_mode": {
                            "type": "string",
                            "default": "insert",
                            "enum": [
                              "insert",
                              "update",
                              "upsert"
                            ],
                            "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                          },
                          "update_policy": {
                            "type": "string",
                            "enum": [
                              "create_version",
                              "replace",
                              "create_version_preferred",
                              "refuse"
                            ],
                            "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                          },
                          "tags": {
                            "type": "array",
                            "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                            "items": {
                              "$ref": "#/components/schemas/Tag"
                            }
                          },
                          "plugin": {
                            "type": "string",
                            "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                            "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                          },
                          "plugin_config": {
                            "type": "object",
                            "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          }
                        }
                      },
                      "reference": {
                        "type": "string",
                        "nullable": true,
                        "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                      },
                      "shortname": {
                        "type": "string",
                        "nullable": true,
                        "description": "A unique string to set a collection shortname. This can be used for search.\n"
                      },
                      "type": {
                        "type": "string",
                        "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                      },
                      "pin_code": {
                        "type": "string",
                        "nullable": true,
                        "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                      },
                      "uuid": {
                        "type": "string",
                        "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                      },
                      "lookup:_id": {
                        "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                        "type": "object",
                        "properties": {
                          "reference": {
                            "type": "string",
                            "description": "The reference of the collection to lookup.\n"
                          }
                        }
                      },
                      "lookup:_id_parent": {
                        "description": "The lookup to find the parent collection.\n",
                        "type": "object",
                        "properties": {
                          "reference": {
                            "type": "string",
                            "description": "The reference of the collection to lookup.\n"
                          }
                        }
                      }
                    }
                  },
                  "_basetype": {
                    "type": "string",
                    "enum": [
                      "collection"
                    ]
                  },
                  "_count": {
                    "type": "number",
                    "format": "int64",
                    "readOnly": true,
                    "description": "The number of objects in this collection.\n"
                  },
                  "_count_recursive": {
                    "type": "number",
                    "format": "int64",
                    "readOnly": true,
                    "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                  },
                  "_create_object_compiled": {
                    "readOnly": true,
                    "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                    "type": "object",
                    "properties": {
                      "objecttype": {
                        "type": "string",
                        "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                      },
                      "mask_id": {
                        "type": "integer",
                        "format": "int64",
                        "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                      },
                      "pool_id": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                      },
                      "linked_pool_id": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                      },
                      "pool": {
                        "$ref": "#/components/schemas/PoolApi",
                        "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                      },
                      "linked_pool": {
                        "$ref": "#/components/schemas/PoolApi",
                        "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                      },
                      "eas_field": {
                        "type": "string",
                        "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                      },
                      "linked_object_pools": {
                        "type": "object",
                        "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                        "additionalProperties": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      },
                      "hierarchy_linked_object": {
                        "type": "object",
                        "nullable": true,
                        "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                        "properties": {
                          "field": {
                            "type": "string",
                            "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                          }
                        }
                      },
                      "mapping": {
                        "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                        "oneOf": [
                          {
                            "type": "string",
                            "enum": [
                              "standard",
                              "none"
                            ]
                          },
                          {
                            "type": "integer",
                            "format": "int64"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "mapping_recipe_configs": {
                        "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                        "allOf": [
                          {
                            "type": "object",
                            "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                            "additionalProperties": {
                              "type": "object",
                              "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                              "properties": {
                                "params": {
                                  "type": "object",
                                  "additionalProperties": true,
                                  "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                  "example": {
                                    "size": 600,
                                    "format": "png",
                                    "resize_mode": "max",
                                    "jpegquality": 80,
                                    "strip": true
                                  }
                                }
                              },
                              "example": {
                                "imageconverter:browserthumbs": {
                                  "params": {
                                    "size": 1200,
                                    "format": "webp",
                                    "resize_mode": "max"
                                  }
                                },
                                "imageconverter:preview_pool_watermark": {
                                  "params": {
                                    "size": 600,
                                    "format": "jpg"
                                  }
                                }
                              }
                            }
                          }
                        ]
                      },
                      "recognize_series": {
                        "type": "boolean",
                        "default": false,
                        "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                      },
                      "recognize_version": {
                        "type": "boolean",
                        "default": false,
                        "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                      },
                      "update_search_field": {
                        "type": "string",
                        "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                      },
                      "update_mode": {
                        "type": "string",
                        "default": "insert",
                        "enum": [
                          "insert",
                          "update",
                          "upsert"
                        ],
                        "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                      },
                      "update_policy": {
                        "type": "string",
                        "enum": [
                          "create_version",
                          "replace",
                          "create_version_preferred",
                          "refuse"
                        ],
                        "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                      },
                      "tags": {
                        "type": "array",
                        "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                        "items": {
                          "$ref": "#/components/schemas/Tag"
                        }
                      },
                      "plugin": {
                        "type": "string",
                        "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                        "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                      },
                      "plugin_config": {
                        "type": "object",
                        "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                        "additionalProperties": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      }
                    }
                  },
                  "_generated_rights": {
                    "type": "object",
                    "readOnly": true,
                    "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                    "properties": {
                      "create": {
                        "type": "object",
                        "properties": {}
                      },
                      "create_in_collection": {
                        "type": "object",
                        "properties": {}
                      },
                      "read": {
                        "type": "object",
                        "properties": {}
                      },
                      "write": {
                        "type": "object",
                        "properties": {}
                      },
                      "delete": {
                        "type": "object",
                        "properties": {}
                      },
                      "asset_upload": {
                        "type": "object",
                        "properties": {}
                      },
                      "asset_show": {
                        "type": "object",
                        "properties": {}
                      },
                      "asset_download": {
                        "type": "object",
                        "properties": {}
                      },
                      "mask": {
                        "type": "object",
                        "properties": {}
                      },
                      "link": {
                        "type": "object",
                        "properties": {}
                      },
                      "acl": {
                        "type": "object",
                        "properties": {}
                      },
                      "change_owner": {
                        "type": "object",
                        "properties": {}
                      },
                      "unlink": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_read": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_write": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_acl": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_delete": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_create": {
                        "type": "object",
                        "properties": {}
                      },
                      "owner": {
                        "type": "object",
                        "properties": {}
                      }
                    }
                  },
                  "_has_acl": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                  },
                  "_has_children": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                  },
                  "_has_remote_objects": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                  },
                  "_level": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                  },
                  "_acl": {
                    "type": "array",
                    "items": {
                      "description": "List of permissions.",
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                        },
                        "who": {
                          "type": "object",
                          "properties": {
                            "_basetype": {
                              "type": "string",
                              "enum": [
                                "user",
                                "group"
                              ]
                            },
                            "_owner": {
                              "type": "boolean",
                              "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                            },
                            "_pool_contact": {
                              "type": "boolean",
                              "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                            },
                            "user": {
                              "type": "object",
                              "properties": {
                                "_id": {
                                  "type": "number",
                                  "format": "int64",
                                  "description": "The id of the user.\n"
                                },
                                "_version": {
                                  "type": "number",
                                  "readOnly": true,
                                  "format": "int64",
                                  "description": "The version of the user record.\n"
                                },
                                "type": {
                                  "type": "string",
                                  "readOnly": true,
                                  "enum": [
                                    "system",
                                    "easydb",
                                    "easydb_self_register",
                                    "anonymous",
                                    "collection",
                                    "email",
                                    "ldap",
                                    "sso"
                                  ]
                                },
                                "_generated_displayname": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                },
                                "login": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "Set for users of type `collection` or `email`.\n"
                                },
                                "frontend_language": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "The preferred frontend language of the user (BCP 47)\n"
                                }
                              }
                            },
                            "group": {
                              "type": "object",
                              "properties": {
                                "_id": {
                                  "type": "number",
                                  "format": "int64",
                                  "description": "The id of the group.\n"
                                },
                                "_generated_displayname": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                }
                              }
                            }
                          }
                        },
                        "sticky": {
                          "type": "boolean",
                          "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                        },
                        "active": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                        },
                        "_right_preset": {
                          "type": "number",
                          "format": "int64",
                          "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                        },
                        "when": {
                          "type": "object",
                          "properties": {
                            "from": {
                              "type": "string",
                              "format": "iso8601_date",
                              "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                            },
                            "to": {
                              "type": "string",
                              "format": "iso8601_date"
                            }
                          }
                        },
                        "rights": {
                          "description": "Object which carries the permissions granted by this item.\n",
                          "type": "object",
                          "additionalProperties": {
                            "type": "object",
                            "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                            "properties": {
                              "_grantable": {
                                "type": "boolean",
                                "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                              },
                              "allow_update_and_remove": {
                                "type": "boolean",
                                "description": "Flag to allow to update or remove a file id from a column.\n"
                              },
                              "classes": {
                                "type": "array",
                                "description": "List of classes this permission if given for. An empty list matches all.\n",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "extensions": {
                                "type": "array",
                                "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "versions": {
                                "type": "array",
                                "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "limit": {
                                "type": "string",
                                "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                              },
                              "mask_ids": {
                                "type": "object",
                                "additionalProperties": {
                                  "description": "The key is the object type ID.\n",
                                  "type": "array",
                                  "items": {
                                    "oneOf": [
                                      {
                                        "type": "string",
                                        "description": "Set to `standard` for the standard mask.\n",
                                        "enum": [
                                          "standard"
                                        ]
                                      },
                                      {
                                        "type": "integer",
                                        "description": "The mask id given the permission for.\n",
                                        "minimum": 1
                                      }
                                    ]
                                  }
                                }
                              },
                              "column_ids": {
                                "description": "List of column api ids to apply this permission to.\n",
                                "type": "array",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "objecttype_ids": {
                                "description": "List of object type ids to apply this permission to.\n",
                                "type": "array",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "pool_ids": {
                                "description": "List of pool IDs to apply this permission to.\n",
                                "type": "array",
                                "items": {
                                  "type": "integer"
                                }
                              }
                            }
                          }
                        },
                        "tagfilter": {
                          "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                          "type": "object",
                          "properties": {
                            "any": {
                              "type": "array",
                              "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                              "items": {
                                "type": "integer"
                              }
                            },
                            "all": {
                              "type": "array",
                              "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                              "items": {
                                "type": "integer"
                              }
                            },
                            "not": {
                              "type": "array",
                              "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                              "items": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "send_email_notification": {
                          "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                          "type": "object",
                          "properties": {
                            "text": {
                              "description": "The text included in the email.\n",
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "_private_acl": {
                    "type": "boolean",
                    "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                  },
                  "_path": {
                    "type": "array",
                    "readOnly": true,
                    "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                    "items": {
                      "type": "object",
                      "properties": {
                        "_basetype": {
                          "type": "string",
                          "enum": [
                            "collection"
                          ]
                        },
                        "collection": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "integer"
                            },
                            "_id_parent": {
                              "type": "integer"
                            },
                            "_version": {
                              "type": "integer"
                            },
                            "displayname": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "_invalid_acl": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                  },
                  "_owner": {
                    "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                    "type": "object",
                    "properties": {
                      "_basetype": {
                        "type": "string",
                        "enum": [
                          "user",
                          "group"
                        ]
                      },
                      "_owner": {
                        "type": "boolean",
                        "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                      },
                      "_pool_contact": {
                        "type": "boolean",
                        "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                      },
                      "user": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "The id of the user.\n"
                          },
                          "_version": {
                            "type": "number",
                            "readOnly": true,
                            "format": "int64",
                            "description": "The version of the user record.\n"
                          },
                          "type": {
                            "type": "string",
                            "readOnly": true,
                            "enum": [
                              "system",
                              "easydb",
                              "easydb_self_register",
                              "anonymous",
                              "collection",
                              "email",
                              "ldap",
                              "sso"
                            ]
                          },
                          "_generated_displayname": {
                            "type": "string",
                            "readOnly": true,
                            "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                          },
                          "login": {
                            "type": "string",
                            "readOnly": true,
                            "description": "Set for users of type `collection` or `email`.\n"
                          },
                          "frontend_language": {
                            "type": "string",
                            "readOnly": true,
                            "description": "The preferred frontend language of the user (BCP 47)\n"
                          }
                        }
                      },
                      "group": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "The id of the group.\n"
                          },
                          "_generated_displayname": {
                            "type": "string",
                            "readOnly": true,
                            "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                          }
                        }
                      }
                    }
                  },
                  "objects": {
                    "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "_global_object_id": {
                          "type": "string",
                          "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "lookup:_global_object_id": {
                          "type": "object",
                          "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                          "properties": {
                            "_allow_defer": {
                              "type": "boolean"
                            },
                            "_objecttype": {
                              "type": "string"
                            },
                            "_system_object_id": {
                              "type": "integer"
                            },
                            "_uuid": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "_hotfolder_upload_urls": {
                    "description": "A list of URLs to upload files into this collection.\n",
                    "type": "array",
                    "readOnly": true,
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                          "type": "string",
                          "enum": [
                            "webdav",
                            "webdav-hotfolder"
                          ]
                        },
                        "url": {
                          "type": "string",
                          "format": "url"
                        }
                      }
                    }
                  },
                  "_has_pin": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                  },
                  "pin_ok": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                  },
                  "_created_at": {
                    "type": "string",
                    "format": "RFC3339_date",
                    "readOnly": true,
                    "description": "Timestamp when this collection was created.\n"
                  },
                  "_updated_at": {
                    "type": "string",
                    "format": "RFC3339_date",
                    "readOnly": true,
                    "description": "Timestamp when this collection was updated.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The response contains the collection created, including the issued `_id`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "collection": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                        },
                        "_id_parent": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "nullable": true,
                          "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                        },
                        "_version": {
                          "type": "number",
                          "format": "int64",
                          "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                        },
                        "children_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                        },
                        "objects_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                        },
                        "is_system_collection": {
                          "type": "boolean",
                          "readOnly": true,
                          "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "displayname": {
                          "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "description": {
                          "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "create_object": {
                          "nullable": true,
                          "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                          "type": "object",
                          "properties": {
                            "objecttype": {
                              "type": "string",
                              "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                            },
                            "mask_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                            },
                            "pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                            },
                            "linked_pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                            },
                            "pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                            },
                            "linked_pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                            },
                            "eas_field": {
                              "type": "string",
                              "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                            },
                            "linked_object_pools": {
                              "type": "object",
                              "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            },
                            "hierarchy_linked_object": {
                              "type": "object",
                              "nullable": true,
                              "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                                }
                              }
                            },
                            "mapping": {
                              "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                              "oneOf": [
                                {
                                  "type": "string",
                                  "enum": [
                                    "standard",
                                    "none"
                                  ]
                                },
                                {
                                  "type": "integer",
                                  "format": "int64"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "mapping_recipe_configs": {
                              "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                              "allOf": [
                                {
                                  "type": "object",
                                  "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                  "additionalProperties": {
                                    "type": "object",
                                    "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                    "properties": {
                                      "params": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                        "example": {
                                          "size": 600,
                                          "format": "png",
                                          "resize_mode": "max",
                                          "jpegquality": 80,
                                          "strip": true
                                        }
                                      }
                                    },
                                    "example": {
                                      "imageconverter:browserthumbs": {
                                        "params": {
                                          "size": 1200,
                                          "format": "webp",
                                          "resize_mode": "max"
                                        }
                                      },
                                      "imageconverter:preview_pool_watermark": {
                                        "params": {
                                          "size": 600,
                                          "format": "jpg"
                                        }
                                      }
                                    }
                                  }
                                }
                              ]
                            },
                            "recognize_series": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                            },
                            "recognize_version": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                            },
                            "update_search_field": {
                              "type": "string",
                              "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                            },
                            "update_mode": {
                              "type": "string",
                              "default": "insert",
                              "enum": [
                                "insert",
                                "update",
                                "upsert"
                              ],
                              "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                            },
                            "update_policy": {
                              "type": "string",
                              "enum": [
                                "create_version",
                                "replace",
                                "create_version_preferred",
                                "refuse"
                              ],
                              "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                            },
                            "tags": {
                              "type": "array",
                              "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                              "items": {
                                "$ref": "#/components/schemas/Tag"
                              }
                            },
                            "plugin": {
                              "type": "string",
                              "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                              "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                            },
                            "plugin_config": {
                              "type": "object",
                              "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            }
                          }
                        },
                        "reference": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                        },
                        "shortname": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection shortname. This can be used for search.\n"
                        },
                        "type": {
                          "type": "string",
                          "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                        },
                        "pin_code": {
                          "type": "string",
                          "nullable": true,
                          "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                        },
                        "uuid": {
                          "type": "string",
                          "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                        },
                        "lookup:_id": {
                          "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        },
                        "lookup:_id_parent": {
                          "description": "The lookup to find the parent collection.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        }
                      }
                    },
                    "_basetype": {
                      "type": "string",
                      "enum": [
                        "collection"
                      ]
                    },
                    "_count": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection.\n"
                    },
                    "_count_recursive": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                    },
                    "_create_object_compiled": {
                      "readOnly": true,
                      "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                      "type": "object",
                      "properties": {
                        "objecttype": {
                          "type": "string",
                          "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                        },
                        "mask_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                        },
                        "pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                        },
                        "linked_pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                        },
                        "pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                        },
                        "linked_pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                        },
                        "eas_field": {
                          "type": "string",
                          "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                        },
                        "linked_object_pools": {
                          "type": "object",
                          "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "hierarchy_linked_object": {
                          "type": "object",
                          "nullable": true,
                          "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                          "properties": {
                            "field": {
                              "type": "string",
                              "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                            }
                          }
                        },
                        "mapping": {
                          "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                          "oneOf": [
                            {
                              "type": "string",
                              "enum": [
                                "standard",
                                "none"
                              ]
                            },
                            {
                              "type": "integer",
                              "format": "int64"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mapping_recipe_configs": {
                          "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                          "allOf": [
                            {
                              "type": "object",
                              "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                              "additionalProperties": {
                                "type": "object",
                                "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                "properties": {
                                  "params": {
                                    "type": "object",
                                    "additionalProperties": true,
                                    "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                    "example": {
                                      "size": 600,
                                      "format": "png",
                                      "resize_mode": "max",
                                      "jpegquality": 80,
                                      "strip": true
                                    }
                                  }
                                },
                                "example": {
                                  "imageconverter:browserthumbs": {
                                    "params": {
                                      "size": 1200,
                                      "format": "webp",
                                      "resize_mode": "max"
                                    }
                                  },
                                  "imageconverter:preview_pool_watermark": {
                                    "params": {
                                      "size": 600,
                                      "format": "jpg"
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        },
                        "recognize_series": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                        },
                        "recognize_version": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                        },
                        "update_search_field": {
                          "type": "string",
                          "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                        },
                        "update_mode": {
                          "type": "string",
                          "default": "insert",
                          "enum": [
                            "insert",
                            "update",
                            "upsert"
                          ],
                          "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                        },
                        "update_policy": {
                          "type": "string",
                          "enum": [
                            "create_version",
                            "replace",
                            "create_version_preferred",
                            "refuse"
                          ],
                          "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                        },
                        "tags": {
                          "type": "array",
                          "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                          "items": {
                            "$ref": "#/components/schemas/Tag"
                          }
                        },
                        "plugin": {
                          "type": "string",
                          "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                          "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                        },
                        "plugin_config": {
                          "type": "object",
                          "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        }
                      }
                    },
                    "_generated_rights": {
                      "type": "object",
                      "readOnly": true,
                      "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                      "properties": {
                        "create": {
                          "type": "object",
                          "properties": {}
                        },
                        "create_in_collection": {
                          "type": "object",
                          "properties": {}
                        },
                        "read": {
                          "type": "object",
                          "properties": {}
                        },
                        "write": {
                          "type": "object",
                          "properties": {}
                        },
                        "delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_upload": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_show": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_download": {
                          "type": "object",
                          "properties": {}
                        },
                        "mask": {
                          "type": "object",
                          "properties": {}
                        },
                        "link": {
                          "type": "object",
                          "properties": {}
                        },
                        "acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "change_owner": {
                          "type": "object",
                          "properties": {}
                        },
                        "unlink": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_read": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_write": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_create": {
                          "type": "object",
                          "properties": {}
                        },
                        "owner": {
                          "type": "object",
                          "properties": {}
                        }
                      }
                    },
                    "_has_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                    },
                    "_has_children": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                    },
                    "_has_remote_objects": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                    },
                    "_level": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                    },
                    "_acl": {
                      "type": "array",
                      "items": {
                        "description": "List of permissions.",
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                          },
                          "who": {
                            "type": "object",
                            "properties": {
                              "_basetype": {
                                "type": "string",
                                "enum": [
                                  "user",
                                  "group"
                                ]
                              },
                              "_owner": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                              },
                              "_pool_contact": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                              },
                              "user": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the user.\n"
                                  },
                                  "_version": {
                                    "type": "number",
                                    "readOnly": true,
                                    "format": "int64",
                                    "description": "The version of the user record.\n"
                                  },
                                  "type": {
                                    "type": "string",
                                    "readOnly": true,
                                    "enum": [
                                      "system",
                                      "easydb",
                                      "easydb_self_register",
                                      "anonymous",
                                      "collection",
                                      "email",
                                      "ldap",
                                      "sso"
                                    ]
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                  },
                                  "login": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "Set for users of type `collection` or `email`.\n"
                                  },
                                  "frontend_language": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "The preferred frontend language of the user (BCP 47)\n"
                                  }
                                }
                              },
                              "group": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the group.\n"
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                  }
                                }
                              }
                            }
                          },
                          "sticky": {
                            "type": "boolean",
                            "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                          },
                          "active": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                          },
                          "_right_preset": {
                            "type": "number",
                            "format": "int64",
                            "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                          },
                          "when": {
                            "type": "object",
                            "properties": {
                              "from": {
                                "type": "string",
                                "format": "iso8601_date",
                                "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                              },
                              "to": {
                                "type": "string",
                                "format": "iso8601_date"
                              }
                            }
                          },
                          "rights": {
                            "description": "Object which carries the permissions granted by this item.\n",
                            "type": "object",
                            "additionalProperties": {
                              "type": "object",
                              "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                              "properties": {
                                "_grantable": {
                                  "type": "boolean",
                                  "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                                },
                                "allow_update_and_remove": {
                                  "type": "boolean",
                                  "description": "Flag to allow to update or remove a file id from a column.\n"
                                },
                                "classes": {
                                  "type": "array",
                                  "description": "List of classes this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "extensions": {
                                  "type": "array",
                                  "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "versions": {
                                  "type": "array",
                                  "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "limit": {
                                  "type": "string",
                                  "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                                },
                                "mask_ids": {
                                  "type": "object",
                                  "additionalProperties": {
                                    "description": "The key is the object type ID.\n",
                                    "type": "array",
                                    "items": {
                                      "oneOf": [
                                        {
                                          "type": "string",
                                          "description": "Set to `standard` for the standard mask.\n",
                                          "enum": [
                                            "standard"
                                          ]
                                        },
                                        {
                                          "type": "integer",
                                          "description": "The mask id given the permission for.\n",
                                          "minimum": 1
                                        }
                                      ]
                                    }
                                  }
                                },
                                "column_ids": {
                                  "description": "List of column api ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "objecttype_ids": {
                                  "description": "List of object type ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "pool_ids": {
                                  "description": "List of pool IDs to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                }
                              }
                            }
                          },
                          "tagfilter": {
                            "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                            "type": "object",
                            "properties": {
                              "any": {
                                "type": "array",
                                "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "all": {
                                "type": "array",
                                "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "not": {
                                "type": "array",
                                "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              }
                            }
                          },
                          "send_email_notification": {
                            "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                            "type": "object",
                            "properties": {
                              "text": {
                                "description": "The text included in the email.\n",
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_private_acl": {
                      "type": "boolean",
                      "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                    },
                    "_path": {
                      "type": "array",
                      "readOnly": true,
                      "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_basetype": {
                            "type": "string",
                            "enum": [
                              "collection"
                            ]
                          },
                          "collection": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "integer"
                              },
                              "_id_parent": {
                                "type": "integer"
                              },
                              "_version": {
                                "type": "integer"
                              },
                              "displayname": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_invalid_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                    },
                    "_owner": {
                      "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                      "type": "object",
                      "properties": {
                        "_basetype": {
                          "type": "string",
                          "enum": [
                            "user",
                            "group"
                          ]
                        },
                        "_owner": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                        },
                        "_pool_contact": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                        },
                        "user": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the user.\n"
                            },
                            "_version": {
                              "type": "number",
                              "readOnly": true,
                              "format": "int64",
                              "description": "The version of the user record.\n"
                            },
                            "type": {
                              "type": "string",
                              "readOnly": true,
                              "enum": [
                                "system",
                                "easydb",
                                "easydb_self_register",
                                "anonymous",
                                "collection",
                                "email",
                                "ldap",
                                "sso"
                              ]
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                            },
                            "login": {
                              "type": "string",
                              "readOnly": true,
                              "description": "Set for users of type `collection` or `email`.\n"
                            },
                            "frontend_language": {
                              "type": "string",
                              "readOnly": true,
                              "description": "The preferred frontend language of the user (BCP 47)\n"
                            }
                          }
                        },
                        "group": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the group.\n"
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                            }
                          }
                        }
                      }
                    },
                    "objects": {
                      "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_global_object_id": {
                            "type": "string",
                            "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                          },
                          "webfrontend_props": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                          },
                          "lookup:_global_object_id": {
                            "type": "object",
                            "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                            "properties": {
                              "_allow_defer": {
                                "type": "boolean"
                              },
                              "_objecttype": {
                                "type": "string"
                              },
                              "_system_object_id": {
                                "type": "integer"
                              },
                              "_uuid": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_hotfolder_upload_urls": {
                      "description": "A list of URLs to upload files into this collection.\n",
                      "type": "array",
                      "readOnly": true,
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                            "type": "string",
                            "enum": [
                              "webdav",
                              "webdav-hotfolder"
                            ]
                          },
                          "url": {
                            "type": "string",
                            "format": "url"
                          }
                        }
                      }
                    },
                    "_has_pin": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                    },
                    "pin_ok": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                    },
                    "_created_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was created.\n"
                    },
                    "_updated_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was updated.\n"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The collection owner cannot grant one of the collection's shared\nrights for an object it contains — whether a share was added, an\nexisting share's rights were edited, or an object was added — and the\ncaller has `BAG_ACL`. The check runs on every save endpoint. Re-send\nwith `allow_invalid_acl=true` to store the collection with sharing\ndisabled.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the\nresponse identifies which validation rejected the request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionRemoveNotAllObjectsFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required `BAG_*` permission on the\ncollection (or a required system right). See `code` for the\nspecific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/collection/{collectionId}": {
      "x-path": "/collection",
      "description": "Operate on a single collection addressed by its `_id`. `GET` retrieves\nthe collection, `POST` updates it (including moving it to a new parent),\nand `DELETE` removes it together with all of its child collections.\n",
      "get": {
        "summary": "Retrieve a collection.",
        "description": "* The user needs `BAG_READ` to retrieve a collection.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "collection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The collection id of the collection to access.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The response contains the collection.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "collection": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                        },
                        "_id_parent": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "nullable": true,
                          "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                        },
                        "_version": {
                          "type": "number",
                          "format": "int64",
                          "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                        },
                        "children_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                        },
                        "objects_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                        },
                        "is_system_collection": {
                          "type": "boolean",
                          "readOnly": true,
                          "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "displayname": {
                          "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "description": {
                          "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "create_object": {
                          "nullable": true,
                          "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                          "type": "object",
                          "properties": {
                            "objecttype": {
                              "type": "string",
                              "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                            },
                            "mask_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                            },
                            "pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                            },
                            "linked_pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                            },
                            "pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                            },
                            "linked_pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                            },
                            "eas_field": {
                              "type": "string",
                              "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                            },
                            "linked_object_pools": {
                              "type": "object",
                              "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            },
                            "hierarchy_linked_object": {
                              "type": "object",
                              "nullable": true,
                              "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                                }
                              }
                            },
                            "mapping": {
                              "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                              "oneOf": [
                                {
                                  "type": "string",
                                  "enum": [
                                    "standard",
                                    "none"
                                  ]
                                },
                                {
                                  "type": "integer",
                                  "format": "int64"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "mapping_recipe_configs": {
                              "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                              "allOf": [
                                {
                                  "type": "object",
                                  "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                  "additionalProperties": {
                                    "type": "object",
                                    "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                    "properties": {
                                      "params": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                        "example": {
                                          "size": 600,
                                          "format": "png",
                                          "resize_mode": "max",
                                          "jpegquality": 80,
                                          "strip": true
                                        }
                                      }
                                    },
                                    "example": {
                                      "imageconverter:browserthumbs": {
                                        "params": {
                                          "size": 1200,
                                          "format": "webp",
                                          "resize_mode": "max"
                                        }
                                      },
                                      "imageconverter:preview_pool_watermark": {
                                        "params": {
                                          "size": 600,
                                          "format": "jpg"
                                        }
                                      }
                                    }
                                  }
                                }
                              ]
                            },
                            "recognize_series": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                            },
                            "recognize_version": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                            },
                            "update_search_field": {
                              "type": "string",
                              "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                            },
                            "update_mode": {
                              "type": "string",
                              "default": "insert",
                              "enum": [
                                "insert",
                                "update",
                                "upsert"
                              ],
                              "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                            },
                            "update_policy": {
                              "type": "string",
                              "enum": [
                                "create_version",
                                "replace",
                                "create_version_preferred",
                                "refuse"
                              ],
                              "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                            },
                            "tags": {
                              "type": "array",
                              "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                              "items": {
                                "$ref": "#/components/schemas/Tag"
                              }
                            },
                            "plugin": {
                              "type": "string",
                              "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                              "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                            },
                            "plugin_config": {
                              "type": "object",
                              "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            }
                          }
                        },
                        "reference": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                        },
                        "shortname": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection shortname. This can be used for search.\n"
                        },
                        "type": {
                          "type": "string",
                          "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                        },
                        "pin_code": {
                          "type": "string",
                          "nullable": true,
                          "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                        },
                        "uuid": {
                          "type": "string",
                          "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                        },
                        "lookup:_id": {
                          "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        },
                        "lookup:_id_parent": {
                          "description": "The lookup to find the parent collection.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        }
                      }
                    },
                    "_basetype": {
                      "type": "string",
                      "enum": [
                        "collection"
                      ]
                    },
                    "_count": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection.\n"
                    },
                    "_count_recursive": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                    },
                    "_create_object_compiled": {
                      "readOnly": true,
                      "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                      "type": "object",
                      "properties": {
                        "objecttype": {
                          "type": "string",
                          "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                        },
                        "mask_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                        },
                        "pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                        },
                        "linked_pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                        },
                        "pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                        },
                        "linked_pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                        },
                        "eas_field": {
                          "type": "string",
                          "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                        },
                        "linked_object_pools": {
                          "type": "object",
                          "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "hierarchy_linked_object": {
                          "type": "object",
                          "nullable": true,
                          "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                          "properties": {
                            "field": {
                              "type": "string",
                              "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                            }
                          }
                        },
                        "mapping": {
                          "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                          "oneOf": [
                            {
                              "type": "string",
                              "enum": [
                                "standard",
                                "none"
                              ]
                            },
                            {
                              "type": "integer",
                              "format": "int64"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mapping_recipe_configs": {
                          "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                          "allOf": [
                            {
                              "type": "object",
                              "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                              "additionalProperties": {
                                "type": "object",
                                "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                "properties": {
                                  "params": {
                                    "type": "object",
                                    "additionalProperties": true,
                                    "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                    "example": {
                                      "size": 600,
                                      "format": "png",
                                      "resize_mode": "max",
                                      "jpegquality": 80,
                                      "strip": true
                                    }
                                  }
                                },
                                "example": {
                                  "imageconverter:browserthumbs": {
                                    "params": {
                                      "size": 1200,
                                      "format": "webp",
                                      "resize_mode": "max"
                                    }
                                  },
                                  "imageconverter:preview_pool_watermark": {
                                    "params": {
                                      "size": 600,
                                      "format": "jpg"
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        },
                        "recognize_series": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                        },
                        "recognize_version": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                        },
                        "update_search_field": {
                          "type": "string",
                          "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                        },
                        "update_mode": {
                          "type": "string",
                          "default": "insert",
                          "enum": [
                            "insert",
                            "update",
                            "upsert"
                          ],
                          "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                        },
                        "update_policy": {
                          "type": "string",
                          "enum": [
                            "create_version",
                            "replace",
                            "create_version_preferred",
                            "refuse"
                          ],
                          "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                        },
                        "tags": {
                          "type": "array",
                          "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                          "items": {
                            "$ref": "#/components/schemas/Tag"
                          }
                        },
                        "plugin": {
                          "type": "string",
                          "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                          "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                        },
                        "plugin_config": {
                          "type": "object",
                          "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        }
                      }
                    },
                    "_generated_rights": {
                      "type": "object",
                      "readOnly": true,
                      "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                      "properties": {
                        "create": {
                          "type": "object",
                          "properties": {}
                        },
                        "create_in_collection": {
                          "type": "object",
                          "properties": {}
                        },
                        "read": {
                          "type": "object",
                          "properties": {}
                        },
                        "write": {
                          "type": "object",
                          "properties": {}
                        },
                        "delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_upload": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_show": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_download": {
                          "type": "object",
                          "properties": {}
                        },
                        "mask": {
                          "type": "object",
                          "properties": {}
                        },
                        "link": {
                          "type": "object",
                          "properties": {}
                        },
                        "acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "change_owner": {
                          "type": "object",
                          "properties": {}
                        },
                        "unlink": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_read": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_write": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_create": {
                          "type": "object",
                          "properties": {}
                        },
                        "owner": {
                          "type": "object",
                          "properties": {}
                        }
                      }
                    },
                    "_has_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                    },
                    "_has_children": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                    },
                    "_has_remote_objects": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                    },
                    "_level": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                    },
                    "_acl": {
                      "type": "array",
                      "items": {
                        "description": "List of permissions.",
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                          },
                          "who": {
                            "type": "object",
                            "properties": {
                              "_basetype": {
                                "type": "string",
                                "enum": [
                                  "user",
                                  "group"
                                ]
                              },
                              "_owner": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                              },
                              "_pool_contact": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                              },
                              "user": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the user.\n"
                                  },
                                  "_version": {
                                    "type": "number",
                                    "readOnly": true,
                                    "format": "int64",
                                    "description": "The version of the user record.\n"
                                  },
                                  "type": {
                                    "type": "string",
                                    "readOnly": true,
                                    "enum": [
                                      "system",
                                      "easydb",
                                      "easydb_self_register",
                                      "anonymous",
                                      "collection",
                                      "email",
                                      "ldap",
                                      "sso"
                                    ]
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                  },
                                  "login": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "Set for users of type `collection` or `email`.\n"
                                  },
                                  "frontend_language": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "The preferred frontend language of the user (BCP 47)\n"
                                  }
                                }
                              },
                              "group": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the group.\n"
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                  }
                                }
                              }
                            }
                          },
                          "sticky": {
                            "type": "boolean",
                            "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                          },
                          "active": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                          },
                          "_right_preset": {
                            "type": "number",
                            "format": "int64",
                            "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                          },
                          "when": {
                            "type": "object",
                            "properties": {
                              "from": {
                                "type": "string",
                                "format": "iso8601_date",
                                "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                              },
                              "to": {
                                "type": "string",
                                "format": "iso8601_date"
                              }
                            }
                          },
                          "rights": {
                            "description": "Object which carries the permissions granted by this item.\n",
                            "type": "object",
                            "additionalProperties": {
                              "type": "object",
                              "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                              "properties": {
                                "_grantable": {
                                  "type": "boolean",
                                  "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                                },
                                "allow_update_and_remove": {
                                  "type": "boolean",
                                  "description": "Flag to allow to update or remove a file id from a column.\n"
                                },
                                "classes": {
                                  "type": "array",
                                  "description": "List of classes this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "extensions": {
                                  "type": "array",
                                  "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "versions": {
                                  "type": "array",
                                  "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "limit": {
                                  "type": "string",
                                  "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                                },
                                "mask_ids": {
                                  "type": "object",
                                  "additionalProperties": {
                                    "description": "The key is the object type ID.\n",
                                    "type": "array",
                                    "items": {
                                      "oneOf": [
                                        {
                                          "type": "string",
                                          "description": "Set to `standard` for the standard mask.\n",
                                          "enum": [
                                            "standard"
                                          ]
                                        },
                                        {
                                          "type": "integer",
                                          "description": "The mask id given the permission for.\n",
                                          "minimum": 1
                                        }
                                      ]
                                    }
                                  }
                                },
                                "column_ids": {
                                  "description": "List of column api ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "objecttype_ids": {
                                  "description": "List of object type ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "pool_ids": {
                                  "description": "List of pool IDs to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                }
                              }
                            }
                          },
                          "tagfilter": {
                            "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                            "type": "object",
                            "properties": {
                              "any": {
                                "type": "array",
                                "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "all": {
                                "type": "array",
                                "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "not": {
                                "type": "array",
                                "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              }
                            }
                          },
                          "send_email_notification": {
                            "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                            "type": "object",
                            "properties": {
                              "text": {
                                "description": "The text included in the email.\n",
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_private_acl": {
                      "type": "boolean",
                      "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                    },
                    "_path": {
                      "type": "array",
                      "readOnly": true,
                      "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_basetype": {
                            "type": "string",
                            "enum": [
                              "collection"
                            ]
                          },
                          "collection": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "integer"
                              },
                              "_id_parent": {
                                "type": "integer"
                              },
                              "_version": {
                                "type": "integer"
                              },
                              "displayname": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_invalid_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                    },
                    "_owner": {
                      "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                      "type": "object",
                      "properties": {
                        "_basetype": {
                          "type": "string",
                          "enum": [
                            "user",
                            "group"
                          ]
                        },
                        "_owner": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                        },
                        "_pool_contact": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                        },
                        "user": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the user.\n"
                            },
                            "_version": {
                              "type": "number",
                              "readOnly": true,
                              "format": "int64",
                              "description": "The version of the user record.\n"
                            },
                            "type": {
                              "type": "string",
                              "readOnly": true,
                              "enum": [
                                "system",
                                "easydb",
                                "easydb_self_register",
                                "anonymous",
                                "collection",
                                "email",
                                "ldap",
                                "sso"
                              ]
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                            },
                            "login": {
                              "type": "string",
                              "readOnly": true,
                              "description": "Set for users of type `collection` or `email`.\n"
                            },
                            "frontend_language": {
                              "type": "string",
                              "readOnly": true,
                              "description": "The preferred frontend language of the user (BCP 47)\n"
                            }
                          }
                        },
                        "group": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the group.\n"
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                            }
                          }
                        }
                      }
                    },
                    "objects": {
                      "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_global_object_id": {
                            "type": "string",
                            "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                          },
                          "webfrontend_props": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                          },
                          "lookup:_global_object_id": {
                            "type": "object",
                            "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                            "properties": {
                              "_allow_defer": {
                                "type": "boolean"
                              },
                              "_objecttype": {
                                "type": "string"
                              },
                              "_system_object_id": {
                                "type": "integer"
                              },
                              "_uuid": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_hotfolder_upload_urls": {
                      "description": "A list of URLs to upload files into this collection.\n",
                      "type": "array",
                      "readOnly": true,
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                            "type": "string",
                            "enum": [
                              "webdav",
                              "webdav-hotfolder"
                            ]
                          },
                          "url": {
                            "type": "string",
                            "format": "url"
                          }
                        }
                      }
                    },
                    "_has_pin": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                    },
                    "pin_ok": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                    },
                    "_created_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was created.\n"
                    },
                    "_updated_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was updated.\n"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required `BAG_*` permission on the\ncollection (or a required system right). See `code` for the\nspecific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The collection addressed by the URL does not exist.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Update collection.",
        "description": "* The user needs `BAG_WRITE` to update a collection.\n* Moving a collection to a new parent requires `BAG_CREATE` in the new parent and `BAG_ACL` in the current collection.\n  When moving a collection, the owner is automatically set to the owner of the parent. This includes all child collections.\n* New ACL items with `send_email_notification` will sent out and email.\n* To set `_private_acl` or `_acl`the user needs `BAG_ACL`.\n* Adding or editing a shared right is validated against the owner's grantable rights; a share the owner cannot grant returns `202` (see below) unless `allow_invalid_acl=true`.\n* `COLLECTION_UPDATE` event is written.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "collection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The collection id of the collection to access.\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "Allow storing the collection even if the owner doesn't have the necessary\npermissions for all objects to share the rights defined in the `_acl` property\nof the collection. The `_invalid_acl` flag will be set, if the user doesn't\nhave sufficient permissions to share all objects of the collection. The user\nneeds the permission `BAG_ACL` for the collection in order to use this\nparameter.\n\nDiffers from easydb 5: this confirmation is driven by the boolean\n`allow_invalid_acl` parameter. easydb 5 instead resolves the `202`\nconfirmation with a `collection_rights_policy` query parameter; there is no\n`allow_invalid_acl` parameter in easydb 5.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, the invalid-ACL validity check (whether the collection owner may\ngrant the rights of all linked objects) is not run inline. Instead a queued\n`ACTION_COLLECTION_ACL_CHECK` job is scheduled and the request returns\nimmediately, before the check has resolved.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "collection": {
                    "type": "object",
                    "properties": {
                      "_id": {
                        "type": "number",
                        "format": "int64",
                        "minimum": 1,
                        "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                      },
                      "_id_parent": {
                        "type": "number",
                        "format": "int64",
                        "minimum": 1,
                        "nullable": true,
                        "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                      },
                      "_version": {
                        "type": "number",
                        "format": "int64",
                        "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                      },
                      "children_allowed": {
                        "type": "boolean",
                        "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                      },
                      "objects_allowed": {
                        "type": "boolean",
                        "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                      },
                      "is_system_collection": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                      },
                      "webfrontend_props": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                      },
                      "displayname": {
                        "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                        "type": "object",
                        "properties": {
                          "de-DE": {
                            "type": "string"
                          },
                          "en-US": {
                            "type": "string"
                          }
                        },
                        "example": {
                          "de-DE": "Deutscher text",
                          "en-US": "English text"
                        }
                      },
                      "description": {
                        "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                        "type": "object",
                        "properties": {
                          "de-DE": {
                            "type": "string"
                          },
                          "en-US": {
                            "type": "string"
                          }
                        },
                        "example": {
                          "de-DE": "Deutscher text",
                          "en-US": "English text"
                        }
                      },
                      "create_object": {
                        "nullable": true,
                        "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                        "type": "object",
                        "properties": {
                          "objecttype": {
                            "type": "string",
                            "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                          },
                          "mask_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                          },
                          "pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                          },
                          "linked_pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                          },
                          "pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                          },
                          "linked_pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                          },
                          "eas_field": {
                            "type": "string",
                            "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                          },
                          "linked_object_pools": {
                            "type": "object",
                            "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "hierarchy_linked_object": {
                            "type": "object",
                            "nullable": true,
                            "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                            "properties": {
                              "field": {
                                "type": "string",
                                "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                              }
                            }
                          },
                          "mapping": {
                            "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                            "oneOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "standard",
                                  "none"
                                ]
                              },
                              {
                                "type": "integer",
                                "format": "int64"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "mapping_recipe_configs": {
                            "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                            "allOf": [
                              {
                                "type": "object",
                                "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                  "properties": {
                                    "params": {
                                      "type": "object",
                                      "additionalProperties": true,
                                      "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                      "example": {
                                        "size": 600,
                                        "format": "png",
                                        "resize_mode": "max",
                                        "jpegquality": 80,
                                        "strip": true
                                      }
                                    }
                                  },
                                  "example": {
                                    "imageconverter:browserthumbs": {
                                      "params": {
                                        "size": 1200,
                                        "format": "webp",
                                        "resize_mode": "max"
                                      }
                                    },
                                    "imageconverter:preview_pool_watermark": {
                                      "params": {
                                        "size": 600,
                                        "format": "jpg"
                                      }
                                    }
                                  }
                                }
                              }
                            ]
                          },
                          "recognize_series": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                          },
                          "recognize_version": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                          },
                          "update_search_field": {
                            "type": "string",
                            "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                          },
                          "update_mode": {
                            "type": "string",
                            "default": "insert",
                            "enum": [
                              "insert",
                              "update",
                              "upsert"
                            ],
                            "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                          },
                          "update_policy": {
                            "type": "string",
                            "enum": [
                              "create_version",
                              "replace",
                              "create_version_preferred",
                              "refuse"
                            ],
                            "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                          },
                          "tags": {
                            "type": "array",
                            "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                            "items": {
                              "$ref": "#/components/schemas/Tag"
                            }
                          },
                          "plugin": {
                            "type": "string",
                            "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                            "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                          },
                          "plugin_config": {
                            "type": "object",
                            "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          }
                        }
                      },
                      "reference": {
                        "type": "string",
                        "nullable": true,
                        "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                      },
                      "shortname": {
                        "type": "string",
                        "nullable": true,
                        "description": "A unique string to set a collection shortname. This can be used for search.\n"
                      },
                      "type": {
                        "type": "string",
                        "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                      },
                      "pin_code": {
                        "type": "string",
                        "nullable": true,
                        "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                      },
                      "uuid": {
                        "type": "string",
                        "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                      },
                      "lookup:_id": {
                        "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                        "type": "object",
                        "properties": {
                          "reference": {
                            "type": "string",
                            "description": "The reference of the collection to lookup.\n"
                          }
                        }
                      },
                      "lookup:_id_parent": {
                        "description": "The lookup to find the parent collection.\n",
                        "type": "object",
                        "properties": {
                          "reference": {
                            "type": "string",
                            "description": "The reference of the collection to lookup.\n"
                          }
                        }
                      }
                    }
                  },
                  "_basetype": {
                    "type": "string",
                    "enum": [
                      "collection"
                    ]
                  },
                  "_count": {
                    "type": "number",
                    "format": "int64",
                    "readOnly": true,
                    "description": "The number of objects in this collection.\n"
                  },
                  "_count_recursive": {
                    "type": "number",
                    "format": "int64",
                    "readOnly": true,
                    "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                  },
                  "_create_object_compiled": {
                    "readOnly": true,
                    "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                    "type": "object",
                    "properties": {
                      "objecttype": {
                        "type": "string",
                        "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                      },
                      "mask_id": {
                        "type": "integer",
                        "format": "int64",
                        "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                      },
                      "pool_id": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                      },
                      "linked_pool_id": {
                        "type": "integer",
                        "format": "int64",
                        "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                      },
                      "pool": {
                        "$ref": "#/components/schemas/PoolApi",
                        "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                      },
                      "linked_pool": {
                        "$ref": "#/components/schemas/PoolApi",
                        "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                      },
                      "eas_field": {
                        "type": "string",
                        "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                      },
                      "linked_object_pools": {
                        "type": "object",
                        "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                        "additionalProperties": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      },
                      "hierarchy_linked_object": {
                        "type": "object",
                        "nullable": true,
                        "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                        "properties": {
                          "field": {
                            "type": "string",
                            "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                          }
                        }
                      },
                      "mapping": {
                        "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                        "oneOf": [
                          {
                            "type": "string",
                            "enum": [
                              "standard",
                              "none"
                            ]
                          },
                          {
                            "type": "integer",
                            "format": "int64"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "mapping_recipe_configs": {
                        "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                        "allOf": [
                          {
                            "type": "object",
                            "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                            "additionalProperties": {
                              "type": "object",
                              "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                              "properties": {
                                "params": {
                                  "type": "object",
                                  "additionalProperties": true,
                                  "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                  "example": {
                                    "size": 600,
                                    "format": "png",
                                    "resize_mode": "max",
                                    "jpegquality": 80,
                                    "strip": true
                                  }
                                }
                              },
                              "example": {
                                "imageconverter:browserthumbs": {
                                  "params": {
                                    "size": 1200,
                                    "format": "webp",
                                    "resize_mode": "max"
                                  }
                                },
                                "imageconverter:preview_pool_watermark": {
                                  "params": {
                                    "size": 600,
                                    "format": "jpg"
                                  }
                                }
                              }
                            }
                          }
                        ]
                      },
                      "recognize_series": {
                        "type": "boolean",
                        "default": false,
                        "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                      },
                      "recognize_version": {
                        "type": "boolean",
                        "default": false,
                        "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                      },
                      "update_search_field": {
                        "type": "string",
                        "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                      },
                      "update_mode": {
                        "type": "string",
                        "default": "insert",
                        "enum": [
                          "insert",
                          "update",
                          "upsert"
                        ],
                        "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                      },
                      "update_policy": {
                        "type": "string",
                        "enum": [
                          "create_version",
                          "replace",
                          "create_version_preferred",
                          "refuse"
                        ],
                        "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                      },
                      "tags": {
                        "type": "array",
                        "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                        "items": {
                          "$ref": "#/components/schemas/Tag"
                        }
                      },
                      "plugin": {
                        "type": "string",
                        "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                        "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                      },
                      "plugin_config": {
                        "type": "object",
                        "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                        "additionalProperties": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      }
                    }
                  },
                  "_generated_rights": {
                    "type": "object",
                    "readOnly": true,
                    "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                    "properties": {
                      "create": {
                        "type": "object",
                        "properties": {}
                      },
                      "create_in_collection": {
                        "type": "object",
                        "properties": {}
                      },
                      "read": {
                        "type": "object",
                        "properties": {}
                      },
                      "write": {
                        "type": "object",
                        "properties": {}
                      },
                      "delete": {
                        "type": "object",
                        "properties": {}
                      },
                      "asset_upload": {
                        "type": "object",
                        "properties": {}
                      },
                      "asset_show": {
                        "type": "object",
                        "properties": {}
                      },
                      "asset_download": {
                        "type": "object",
                        "properties": {}
                      },
                      "mask": {
                        "type": "object",
                        "properties": {}
                      },
                      "link": {
                        "type": "object",
                        "properties": {}
                      },
                      "acl": {
                        "type": "object",
                        "properties": {}
                      },
                      "change_owner": {
                        "type": "object",
                        "properties": {}
                      },
                      "unlink": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_read": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_write": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_acl": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_delete": {
                        "type": "object",
                        "properties": {}
                      },
                      "bag_create": {
                        "type": "object",
                        "properties": {}
                      },
                      "owner": {
                        "type": "object",
                        "properties": {}
                      }
                    }
                  },
                  "_has_acl": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                  },
                  "_has_children": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                  },
                  "_has_remote_objects": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                  },
                  "_level": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                  },
                  "_acl": {
                    "type": "array",
                    "items": {
                      "description": "List of permissions.",
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                        },
                        "who": {
                          "type": "object",
                          "properties": {
                            "_basetype": {
                              "type": "string",
                              "enum": [
                                "user",
                                "group"
                              ]
                            },
                            "_owner": {
                              "type": "boolean",
                              "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                            },
                            "_pool_contact": {
                              "type": "boolean",
                              "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                            },
                            "user": {
                              "type": "object",
                              "properties": {
                                "_id": {
                                  "type": "number",
                                  "format": "int64",
                                  "description": "The id of the user.\n"
                                },
                                "_version": {
                                  "type": "number",
                                  "readOnly": true,
                                  "format": "int64",
                                  "description": "The version of the user record.\n"
                                },
                                "type": {
                                  "type": "string",
                                  "readOnly": true,
                                  "enum": [
                                    "system",
                                    "easydb",
                                    "easydb_self_register",
                                    "anonymous",
                                    "collection",
                                    "email",
                                    "ldap",
                                    "sso"
                                  ]
                                },
                                "_generated_displayname": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                },
                                "login": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "Set for users of type `collection` or `email`.\n"
                                },
                                "frontend_language": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "The preferred frontend language of the user (BCP 47)\n"
                                }
                              }
                            },
                            "group": {
                              "type": "object",
                              "properties": {
                                "_id": {
                                  "type": "number",
                                  "format": "int64",
                                  "description": "The id of the group.\n"
                                },
                                "_generated_displayname": {
                                  "type": "string",
                                  "readOnly": true,
                                  "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                }
                              }
                            }
                          }
                        },
                        "sticky": {
                          "type": "boolean",
                          "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                        },
                        "active": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                        },
                        "_right_preset": {
                          "type": "number",
                          "format": "int64",
                          "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                        },
                        "when": {
                          "type": "object",
                          "properties": {
                            "from": {
                              "type": "string",
                              "format": "iso8601_date",
                              "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                            },
                            "to": {
                              "type": "string",
                              "format": "iso8601_date"
                            }
                          }
                        },
                        "rights": {
                          "description": "Object which carries the permissions granted by this item.\n",
                          "type": "object",
                          "additionalProperties": {
                            "type": "object",
                            "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                            "properties": {
                              "_grantable": {
                                "type": "boolean",
                                "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                              },
                              "allow_update_and_remove": {
                                "type": "boolean",
                                "description": "Flag to allow to update or remove a file id from a column.\n"
                              },
                              "classes": {
                                "type": "array",
                                "description": "List of classes this permission if given for. An empty list matches all.\n",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "extensions": {
                                "type": "array",
                                "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "versions": {
                                "type": "array",
                                "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "limit": {
                                "type": "string",
                                "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                              },
                              "mask_ids": {
                                "type": "object",
                                "additionalProperties": {
                                  "description": "The key is the object type ID.\n",
                                  "type": "array",
                                  "items": {
                                    "oneOf": [
                                      {
                                        "type": "string",
                                        "description": "Set to `standard` for the standard mask.\n",
                                        "enum": [
                                          "standard"
                                        ]
                                      },
                                      {
                                        "type": "integer",
                                        "description": "The mask id given the permission for.\n",
                                        "minimum": 1
                                      }
                                    ]
                                  }
                                }
                              },
                              "column_ids": {
                                "description": "List of column api ids to apply this permission to.\n",
                                "type": "array",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "objecttype_ids": {
                                "description": "List of object type ids to apply this permission to.\n",
                                "type": "array",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "pool_ids": {
                                "description": "List of pool IDs to apply this permission to.\n",
                                "type": "array",
                                "items": {
                                  "type": "integer"
                                }
                              }
                            }
                          }
                        },
                        "tagfilter": {
                          "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                          "type": "object",
                          "properties": {
                            "any": {
                              "type": "array",
                              "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                              "items": {
                                "type": "integer"
                              }
                            },
                            "all": {
                              "type": "array",
                              "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                              "items": {
                                "type": "integer"
                              }
                            },
                            "not": {
                              "type": "array",
                              "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                              "items": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "send_email_notification": {
                          "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                          "type": "object",
                          "properties": {
                            "text": {
                              "description": "The text included in the email.\n",
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "_private_acl": {
                    "type": "boolean",
                    "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                  },
                  "_path": {
                    "type": "array",
                    "readOnly": true,
                    "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                    "items": {
                      "type": "object",
                      "properties": {
                        "_basetype": {
                          "type": "string",
                          "enum": [
                            "collection"
                          ]
                        },
                        "collection": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "integer"
                            },
                            "_id_parent": {
                              "type": "integer"
                            },
                            "_version": {
                              "type": "integer"
                            },
                            "displayname": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "_invalid_acl": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                  },
                  "_owner": {
                    "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                    "type": "object",
                    "properties": {
                      "_basetype": {
                        "type": "string",
                        "enum": [
                          "user",
                          "group"
                        ]
                      },
                      "_owner": {
                        "type": "boolean",
                        "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                      },
                      "_pool_contact": {
                        "type": "boolean",
                        "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                      },
                      "user": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "The id of the user.\n"
                          },
                          "_version": {
                            "type": "number",
                            "readOnly": true,
                            "format": "int64",
                            "description": "The version of the user record.\n"
                          },
                          "type": {
                            "type": "string",
                            "readOnly": true,
                            "enum": [
                              "system",
                              "easydb",
                              "easydb_self_register",
                              "anonymous",
                              "collection",
                              "email",
                              "ldap",
                              "sso"
                            ]
                          },
                          "_generated_displayname": {
                            "type": "string",
                            "readOnly": true,
                            "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                          },
                          "login": {
                            "type": "string",
                            "readOnly": true,
                            "description": "Set for users of type `collection` or `email`.\n"
                          },
                          "frontend_language": {
                            "type": "string",
                            "readOnly": true,
                            "description": "The preferred frontend language of the user (BCP 47)\n"
                          }
                        }
                      },
                      "group": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "The id of the group.\n"
                          },
                          "_generated_displayname": {
                            "type": "string",
                            "readOnly": true,
                            "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                          }
                        }
                      }
                    }
                  },
                  "objects": {
                    "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "_global_object_id": {
                          "type": "string",
                          "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "lookup:_global_object_id": {
                          "type": "object",
                          "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                          "properties": {
                            "_allow_defer": {
                              "type": "boolean"
                            },
                            "_objecttype": {
                              "type": "string"
                            },
                            "_system_object_id": {
                              "type": "integer"
                            },
                            "_uuid": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "_hotfolder_upload_urls": {
                    "description": "A list of URLs to upload files into this collection.\n",
                    "type": "array",
                    "readOnly": true,
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                          "type": "string",
                          "enum": [
                            "webdav",
                            "webdav-hotfolder"
                          ]
                        },
                        "url": {
                          "type": "string",
                          "format": "url"
                        }
                      }
                    }
                  },
                  "_has_pin": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                  },
                  "pin_ok": {
                    "type": "boolean",
                    "readOnly": true,
                    "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                  },
                  "_created_at": {
                    "type": "string",
                    "format": "RFC3339_date",
                    "readOnly": true,
                    "description": "Timestamp when this collection was created.\n"
                  },
                  "_updated_at": {
                    "type": "string",
                    "format": "RFC3339_date",
                    "readOnly": true,
                    "description": "Timestamp when this collection was updated.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The response contains the collection created, including the issued `_id`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "collection": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                        },
                        "_id_parent": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "nullable": true,
                          "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                        },
                        "_version": {
                          "type": "number",
                          "format": "int64",
                          "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                        },
                        "children_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                        },
                        "objects_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                        },
                        "is_system_collection": {
                          "type": "boolean",
                          "readOnly": true,
                          "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "displayname": {
                          "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "description": {
                          "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "create_object": {
                          "nullable": true,
                          "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                          "type": "object",
                          "properties": {
                            "objecttype": {
                              "type": "string",
                              "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                            },
                            "mask_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                            },
                            "pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                            },
                            "linked_pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                            },
                            "pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                            },
                            "linked_pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                            },
                            "eas_field": {
                              "type": "string",
                              "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                            },
                            "linked_object_pools": {
                              "type": "object",
                              "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            },
                            "hierarchy_linked_object": {
                              "type": "object",
                              "nullable": true,
                              "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                                }
                              }
                            },
                            "mapping": {
                              "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                              "oneOf": [
                                {
                                  "type": "string",
                                  "enum": [
                                    "standard",
                                    "none"
                                  ]
                                },
                                {
                                  "type": "integer",
                                  "format": "int64"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "mapping_recipe_configs": {
                              "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                              "allOf": [
                                {
                                  "type": "object",
                                  "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                  "additionalProperties": {
                                    "type": "object",
                                    "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                    "properties": {
                                      "params": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                        "example": {
                                          "size": 600,
                                          "format": "png",
                                          "resize_mode": "max",
                                          "jpegquality": 80,
                                          "strip": true
                                        }
                                      }
                                    },
                                    "example": {
                                      "imageconverter:browserthumbs": {
                                        "params": {
                                          "size": 1200,
                                          "format": "webp",
                                          "resize_mode": "max"
                                        }
                                      },
                                      "imageconverter:preview_pool_watermark": {
                                        "params": {
                                          "size": 600,
                                          "format": "jpg"
                                        }
                                      }
                                    }
                                  }
                                }
                              ]
                            },
                            "recognize_series": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                            },
                            "recognize_version": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                            },
                            "update_search_field": {
                              "type": "string",
                              "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                            },
                            "update_mode": {
                              "type": "string",
                              "default": "insert",
                              "enum": [
                                "insert",
                                "update",
                                "upsert"
                              ],
                              "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                            },
                            "update_policy": {
                              "type": "string",
                              "enum": [
                                "create_version",
                                "replace",
                                "create_version_preferred",
                                "refuse"
                              ],
                              "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                            },
                            "tags": {
                              "type": "array",
                              "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                              "items": {
                                "$ref": "#/components/schemas/Tag"
                              }
                            },
                            "plugin": {
                              "type": "string",
                              "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                              "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                            },
                            "plugin_config": {
                              "type": "object",
                              "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            }
                          }
                        },
                        "reference": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                        },
                        "shortname": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection shortname. This can be used for search.\n"
                        },
                        "type": {
                          "type": "string",
                          "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                        },
                        "pin_code": {
                          "type": "string",
                          "nullable": true,
                          "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                        },
                        "uuid": {
                          "type": "string",
                          "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                        },
                        "lookup:_id": {
                          "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        },
                        "lookup:_id_parent": {
                          "description": "The lookup to find the parent collection.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        }
                      }
                    },
                    "_basetype": {
                      "type": "string",
                      "enum": [
                        "collection"
                      ]
                    },
                    "_count": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection.\n"
                    },
                    "_count_recursive": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                    },
                    "_create_object_compiled": {
                      "readOnly": true,
                      "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                      "type": "object",
                      "properties": {
                        "objecttype": {
                          "type": "string",
                          "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                        },
                        "mask_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                        },
                        "pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                        },
                        "linked_pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                        },
                        "pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                        },
                        "linked_pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                        },
                        "eas_field": {
                          "type": "string",
                          "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                        },
                        "linked_object_pools": {
                          "type": "object",
                          "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "hierarchy_linked_object": {
                          "type": "object",
                          "nullable": true,
                          "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                          "properties": {
                            "field": {
                              "type": "string",
                              "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                            }
                          }
                        },
                        "mapping": {
                          "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                          "oneOf": [
                            {
                              "type": "string",
                              "enum": [
                                "standard",
                                "none"
                              ]
                            },
                            {
                              "type": "integer",
                              "format": "int64"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mapping_recipe_configs": {
                          "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                          "allOf": [
                            {
                              "type": "object",
                              "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                              "additionalProperties": {
                                "type": "object",
                                "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                "properties": {
                                  "params": {
                                    "type": "object",
                                    "additionalProperties": true,
                                    "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                    "example": {
                                      "size": 600,
                                      "format": "png",
                                      "resize_mode": "max",
                                      "jpegquality": 80,
                                      "strip": true
                                    }
                                  }
                                },
                                "example": {
                                  "imageconverter:browserthumbs": {
                                    "params": {
                                      "size": 1200,
                                      "format": "webp",
                                      "resize_mode": "max"
                                    }
                                  },
                                  "imageconverter:preview_pool_watermark": {
                                    "params": {
                                      "size": 600,
                                      "format": "jpg"
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        },
                        "recognize_series": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                        },
                        "recognize_version": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                        },
                        "update_search_field": {
                          "type": "string",
                          "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                        },
                        "update_mode": {
                          "type": "string",
                          "default": "insert",
                          "enum": [
                            "insert",
                            "update",
                            "upsert"
                          ],
                          "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                        },
                        "update_policy": {
                          "type": "string",
                          "enum": [
                            "create_version",
                            "replace",
                            "create_version_preferred",
                            "refuse"
                          ],
                          "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                        },
                        "tags": {
                          "type": "array",
                          "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                          "items": {
                            "$ref": "#/components/schemas/Tag"
                          }
                        },
                        "plugin": {
                          "type": "string",
                          "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                          "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                        },
                        "plugin_config": {
                          "type": "object",
                          "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        }
                      }
                    },
                    "_generated_rights": {
                      "type": "object",
                      "readOnly": true,
                      "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                      "properties": {
                        "create": {
                          "type": "object",
                          "properties": {}
                        },
                        "create_in_collection": {
                          "type": "object",
                          "properties": {}
                        },
                        "read": {
                          "type": "object",
                          "properties": {}
                        },
                        "write": {
                          "type": "object",
                          "properties": {}
                        },
                        "delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_upload": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_show": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_download": {
                          "type": "object",
                          "properties": {}
                        },
                        "mask": {
                          "type": "object",
                          "properties": {}
                        },
                        "link": {
                          "type": "object",
                          "properties": {}
                        },
                        "acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "change_owner": {
                          "type": "object",
                          "properties": {}
                        },
                        "unlink": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_read": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_write": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_create": {
                          "type": "object",
                          "properties": {}
                        },
                        "owner": {
                          "type": "object",
                          "properties": {}
                        }
                      }
                    },
                    "_has_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                    },
                    "_has_children": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                    },
                    "_has_remote_objects": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                    },
                    "_level": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                    },
                    "_acl": {
                      "type": "array",
                      "items": {
                        "description": "List of permissions.",
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                          },
                          "who": {
                            "type": "object",
                            "properties": {
                              "_basetype": {
                                "type": "string",
                                "enum": [
                                  "user",
                                  "group"
                                ]
                              },
                              "_owner": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                              },
                              "_pool_contact": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                              },
                              "user": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the user.\n"
                                  },
                                  "_version": {
                                    "type": "number",
                                    "readOnly": true,
                                    "format": "int64",
                                    "description": "The version of the user record.\n"
                                  },
                                  "type": {
                                    "type": "string",
                                    "readOnly": true,
                                    "enum": [
                                      "system",
                                      "easydb",
                                      "easydb_self_register",
                                      "anonymous",
                                      "collection",
                                      "email",
                                      "ldap",
                                      "sso"
                                    ]
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                  },
                                  "login": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "Set for users of type `collection` or `email`.\n"
                                  },
                                  "frontend_language": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "The preferred frontend language of the user (BCP 47)\n"
                                  }
                                }
                              },
                              "group": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the group.\n"
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                  }
                                }
                              }
                            }
                          },
                          "sticky": {
                            "type": "boolean",
                            "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                          },
                          "active": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                          },
                          "_right_preset": {
                            "type": "number",
                            "format": "int64",
                            "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                          },
                          "when": {
                            "type": "object",
                            "properties": {
                              "from": {
                                "type": "string",
                                "format": "iso8601_date",
                                "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                              },
                              "to": {
                                "type": "string",
                                "format": "iso8601_date"
                              }
                            }
                          },
                          "rights": {
                            "description": "Object which carries the permissions granted by this item.\n",
                            "type": "object",
                            "additionalProperties": {
                              "type": "object",
                              "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                              "properties": {
                                "_grantable": {
                                  "type": "boolean",
                                  "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                                },
                                "allow_update_and_remove": {
                                  "type": "boolean",
                                  "description": "Flag to allow to update or remove a file id from a column.\n"
                                },
                                "classes": {
                                  "type": "array",
                                  "description": "List of classes this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "extensions": {
                                  "type": "array",
                                  "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "versions": {
                                  "type": "array",
                                  "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "limit": {
                                  "type": "string",
                                  "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                                },
                                "mask_ids": {
                                  "type": "object",
                                  "additionalProperties": {
                                    "description": "The key is the object type ID.\n",
                                    "type": "array",
                                    "items": {
                                      "oneOf": [
                                        {
                                          "type": "string",
                                          "description": "Set to `standard` for the standard mask.\n",
                                          "enum": [
                                            "standard"
                                          ]
                                        },
                                        {
                                          "type": "integer",
                                          "description": "The mask id given the permission for.\n",
                                          "minimum": 1
                                        }
                                      ]
                                    }
                                  }
                                },
                                "column_ids": {
                                  "description": "List of column api ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "objecttype_ids": {
                                  "description": "List of object type ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "pool_ids": {
                                  "description": "List of pool IDs to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                }
                              }
                            }
                          },
                          "tagfilter": {
                            "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                            "type": "object",
                            "properties": {
                              "any": {
                                "type": "array",
                                "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "all": {
                                "type": "array",
                                "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "not": {
                                "type": "array",
                                "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              }
                            }
                          },
                          "send_email_notification": {
                            "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                            "type": "object",
                            "properties": {
                              "text": {
                                "description": "The text included in the email.\n",
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_private_acl": {
                      "type": "boolean",
                      "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                    },
                    "_path": {
                      "type": "array",
                      "readOnly": true,
                      "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_basetype": {
                            "type": "string",
                            "enum": [
                              "collection"
                            ]
                          },
                          "collection": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "integer"
                              },
                              "_id_parent": {
                                "type": "integer"
                              },
                              "_version": {
                                "type": "integer"
                              },
                              "displayname": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_invalid_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                    },
                    "_owner": {
                      "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                      "type": "object",
                      "properties": {
                        "_basetype": {
                          "type": "string",
                          "enum": [
                            "user",
                            "group"
                          ]
                        },
                        "_owner": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                        },
                        "_pool_contact": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                        },
                        "user": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the user.\n"
                            },
                            "_version": {
                              "type": "number",
                              "readOnly": true,
                              "format": "int64",
                              "description": "The version of the user record.\n"
                            },
                            "type": {
                              "type": "string",
                              "readOnly": true,
                              "enum": [
                                "system",
                                "easydb",
                                "easydb_self_register",
                                "anonymous",
                                "collection",
                                "email",
                                "ldap",
                                "sso"
                              ]
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                            },
                            "login": {
                              "type": "string",
                              "readOnly": true,
                              "description": "Set for users of type `collection` or `email`.\n"
                            },
                            "frontend_language": {
                              "type": "string",
                              "readOnly": true,
                              "description": "The preferred frontend language of the user (BCP 47)\n"
                            }
                          }
                        },
                        "group": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the group.\n"
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                            }
                          }
                        }
                      }
                    },
                    "objects": {
                      "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_global_object_id": {
                            "type": "string",
                            "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                          },
                          "webfrontend_props": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                          },
                          "lookup:_global_object_id": {
                            "type": "object",
                            "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                            "properties": {
                              "_allow_defer": {
                                "type": "boolean"
                              },
                              "_objecttype": {
                                "type": "string"
                              },
                              "_system_object_id": {
                                "type": "integer"
                              },
                              "_uuid": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_hotfolder_upload_urls": {
                      "description": "A list of URLs to upload files into this collection.\n",
                      "type": "array",
                      "readOnly": true,
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                            "type": "string",
                            "enum": [
                              "webdav",
                              "webdav-hotfolder"
                            ]
                          },
                          "url": {
                            "type": "string",
                            "format": "url"
                          }
                        }
                      }
                    },
                    "_has_pin": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                    },
                    "pin_ok": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                    },
                    "_created_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was created.\n"
                    },
                    "_updated_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was updated.\n"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The collection owner cannot grant one of the collection's shared\nrights for an object it contains — whether a share was added, an\nexisting share's rights were edited, or an object was added — and the\ncaller has `BAG_ACL`. The check runs on every save endpoint. Re-send\nwith `allow_invalid_acl=true` to store the collection with sharing\ndisabled.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the\nresponse identifies which validation rejected the request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionRemoveNotAllObjectsFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required `BAG_*` permission on the\ncollection (or a required system right). See `code` for the\nspecific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The collection addressed by the URL does not exist.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete collection. All child collections will be deleted too.",
        "description": "* The user needs `BAG_DELETE` for each collection to be deleted.\n* `COLLECTION_DELETE` event is written for each collection.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "collection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The collection id of the collection to access.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Delete was successful.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      },
                      "required": [
                        "acknowledged"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required `BAG_*` permission on the\ncollection (or a required system right). See `code` for the\nspecific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The collection addressed by the URL does not exist.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/collection/list": {
      "description": "List and create collections. `GET` returns every collection the user has\n`BAG_READ` for, as a flat array (not nested into a tree); `PUT` creates new\ncollections from an array payload.\n",
      "get": {
        "summary": "Retrieve a list of collections.",
        "description": "* Requires an authenticated user.\n* Only collections the user has `BAG_READ` permissions for are returned.\n* This call is slow for non-root users if there are many collections in the system.\n",
        "parameters": [
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "The offset when requesting the collection list."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "The limit when requesting the collection list. Default is _1000_."
          },
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The list of collections.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Array of collections.\n",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "collection": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "minimum": 1,
                            "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                          },
                          "_id_parent": {
                            "type": "number",
                            "format": "int64",
                            "minimum": 1,
                            "nullable": true,
                            "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                          },
                          "_version": {
                            "type": "number",
                            "format": "int64",
                            "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                          },
                          "children_allowed": {
                            "type": "boolean",
                            "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                          },
                          "objects_allowed": {
                            "type": "boolean",
                            "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                          },
                          "is_system_collection": {
                            "type": "boolean",
                            "readOnly": true,
                            "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                          },
                          "webfrontend_props": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                          },
                          "displayname": {
                            "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                            "type": "object",
                            "properties": {
                              "de-DE": {
                                "type": "string"
                              },
                              "en-US": {
                                "type": "string"
                              }
                            },
                            "example": {
                              "de-DE": "Deutscher text",
                              "en-US": "English text"
                            }
                          },
                          "description": {
                            "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                            "type": "object",
                            "properties": {
                              "de-DE": {
                                "type": "string"
                              },
                              "en-US": {
                                "type": "string"
                              }
                            },
                            "example": {
                              "de-DE": "Deutscher text",
                              "en-US": "English text"
                            }
                          },
                          "create_object": {
                            "nullable": true,
                            "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                            "type": "object",
                            "properties": {
                              "objecttype": {
                                "type": "string",
                                "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                              },
                              "mask_id": {
                                "type": "integer",
                                "format": "int64",
                                "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                              },
                              "pool_id": {
                                "type": "integer",
                                "format": "int64",
                                "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                              },
                              "linked_pool_id": {
                                "type": "integer",
                                "format": "int64",
                                "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                              },
                              "pool": {
                                "$ref": "#/components/schemas/PoolApi",
                                "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                              },
                              "linked_pool": {
                                "$ref": "#/components/schemas/PoolApi",
                                "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                              },
                              "eas_field": {
                                "type": "string",
                                "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                              },
                              "linked_object_pools": {
                                "type": "object",
                                "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "additionalProperties": true
                                }
                              },
                              "hierarchy_linked_object": {
                                "type": "object",
                                "nullable": true,
                                "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                                "properties": {
                                  "field": {
                                    "type": "string",
                                    "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                                  }
                                }
                              },
                              "mapping": {
                                "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                                "oneOf": [
                                  {
                                    "type": "string",
                                    "enum": [
                                      "standard",
                                      "none"
                                    ]
                                  },
                                  {
                                    "type": "integer",
                                    "format": "int64"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "mapping_recipe_configs": {
                                "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                                "allOf": [
                                  {
                                    "type": "object",
                                    "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                    "additionalProperties": {
                                      "type": "object",
                                      "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                      "properties": {
                                        "params": {
                                          "type": "object",
                                          "additionalProperties": true,
                                          "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                          "example": {
                                            "size": 600,
                                            "format": "png",
                                            "resize_mode": "max",
                                            "jpegquality": 80,
                                            "strip": true
                                          }
                                        }
                                      },
                                      "example": {
                                        "imageconverter:browserthumbs": {
                                          "params": {
                                            "size": 1200,
                                            "format": "webp",
                                            "resize_mode": "max"
                                          }
                                        },
                                        "imageconverter:preview_pool_watermark": {
                                          "params": {
                                            "size": 600,
                                            "format": "jpg"
                                          }
                                        }
                                      }
                                    }
                                  }
                                ]
                              },
                              "recognize_series": {
                                "type": "boolean",
                                "default": false,
                                "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                              },
                              "recognize_version": {
                                "type": "boolean",
                                "default": false,
                                "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                              },
                              "update_search_field": {
                                "type": "string",
                                "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                              },
                              "update_mode": {
                                "type": "string",
                                "default": "insert",
                                "enum": [
                                  "insert",
                                  "update",
                                  "upsert"
                                ],
                                "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                              },
                              "update_policy": {
                                "type": "string",
                                "enum": [
                                  "create_version",
                                  "replace",
                                  "create_version_preferred",
                                  "refuse"
                                ],
                                "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                              },
                              "tags": {
                                "type": "array",
                                "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                                "items": {
                                  "$ref": "#/components/schemas/Tag"
                                }
                              },
                              "plugin": {
                                "type": "string",
                                "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                                "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                              },
                              "plugin_config": {
                                "type": "object",
                                "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "additionalProperties": true
                                }
                              }
                            }
                          },
                          "reference": {
                            "type": "string",
                            "nullable": true,
                            "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                          },
                          "shortname": {
                            "type": "string",
                            "nullable": true,
                            "description": "A unique string to set a collection shortname. This can be used for search.\n"
                          },
                          "type": {
                            "type": "string",
                            "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                          },
                          "pin_code": {
                            "type": "string",
                            "nullable": true,
                            "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                          },
                          "uuid": {
                            "type": "string",
                            "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                          },
                          "lookup:_id": {
                            "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                            "type": "object",
                            "properties": {
                              "reference": {
                                "type": "string",
                                "description": "The reference of the collection to lookup.\n"
                              }
                            }
                          },
                          "lookup:_id_parent": {
                            "description": "The lookup to find the parent collection.\n",
                            "type": "object",
                            "properties": {
                              "reference": {
                                "type": "string",
                                "description": "The reference of the collection to lookup.\n"
                              }
                            }
                          }
                        }
                      },
                      "_basetype": {
                        "type": "string",
                        "enum": [
                          "collection"
                        ]
                      },
                      "_count": {
                        "type": "number",
                        "format": "int64",
                        "readOnly": true,
                        "description": "The number of objects in this collection.\n"
                      },
                      "_count_recursive": {
                        "type": "number",
                        "format": "int64",
                        "readOnly": true,
                        "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                      },
                      "_create_object_compiled": {
                        "readOnly": true,
                        "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                        "type": "object",
                        "properties": {
                          "objecttype": {
                            "type": "string",
                            "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                          },
                          "mask_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                          },
                          "pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                          },
                          "linked_pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                          },
                          "pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                          },
                          "linked_pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                          },
                          "eas_field": {
                            "type": "string",
                            "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                          },
                          "linked_object_pools": {
                            "type": "object",
                            "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "hierarchy_linked_object": {
                            "type": "object",
                            "nullable": true,
                            "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                            "properties": {
                              "field": {
                                "type": "string",
                                "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                              }
                            }
                          },
                          "mapping": {
                            "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                            "oneOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "standard",
                                  "none"
                                ]
                              },
                              {
                                "type": "integer",
                                "format": "int64"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "mapping_recipe_configs": {
                            "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                            "allOf": [
                              {
                                "type": "object",
                                "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                  "properties": {
                                    "params": {
                                      "type": "object",
                                      "additionalProperties": true,
                                      "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                      "example": {
                                        "size": 600,
                                        "format": "png",
                                        "resize_mode": "max",
                                        "jpegquality": 80,
                                        "strip": true
                                      }
                                    }
                                  },
                                  "example": {
                                    "imageconverter:browserthumbs": {
                                      "params": {
                                        "size": 1200,
                                        "format": "webp",
                                        "resize_mode": "max"
                                      }
                                    },
                                    "imageconverter:preview_pool_watermark": {
                                      "params": {
                                        "size": 600,
                                        "format": "jpg"
                                      }
                                    }
                                  }
                                }
                              }
                            ]
                          },
                          "recognize_series": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                          },
                          "recognize_version": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                          },
                          "update_search_field": {
                            "type": "string",
                            "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                          },
                          "update_mode": {
                            "type": "string",
                            "default": "insert",
                            "enum": [
                              "insert",
                              "update",
                              "upsert"
                            ],
                            "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                          },
                          "update_policy": {
                            "type": "string",
                            "enum": [
                              "create_version",
                              "replace",
                              "create_version_preferred",
                              "refuse"
                            ],
                            "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                          },
                          "tags": {
                            "type": "array",
                            "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                            "items": {
                              "$ref": "#/components/schemas/Tag"
                            }
                          },
                          "plugin": {
                            "type": "string",
                            "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                            "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                          },
                          "plugin_config": {
                            "type": "object",
                            "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          }
                        }
                      },
                      "_generated_rights": {
                        "type": "object",
                        "readOnly": true,
                        "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                        "properties": {
                          "create": {
                            "type": "object",
                            "properties": {}
                          },
                          "create_in_collection": {
                            "type": "object",
                            "properties": {}
                          },
                          "read": {
                            "type": "object",
                            "properties": {}
                          },
                          "write": {
                            "type": "object",
                            "properties": {}
                          },
                          "delete": {
                            "type": "object",
                            "properties": {}
                          },
                          "asset_upload": {
                            "type": "object",
                            "properties": {}
                          },
                          "asset_show": {
                            "type": "object",
                            "properties": {}
                          },
                          "asset_download": {
                            "type": "object",
                            "properties": {}
                          },
                          "mask": {
                            "type": "object",
                            "properties": {}
                          },
                          "link": {
                            "type": "object",
                            "properties": {}
                          },
                          "acl": {
                            "type": "object",
                            "properties": {}
                          },
                          "change_owner": {
                            "type": "object",
                            "properties": {}
                          },
                          "unlink": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_read": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_write": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_acl": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_delete": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_create": {
                            "type": "object",
                            "properties": {}
                          },
                          "owner": {
                            "type": "object",
                            "properties": {}
                          }
                        }
                      },
                      "_has_acl": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                      },
                      "_has_children": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                      },
                      "_has_remote_objects": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                      },
                      "_level": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                      },
                      "_acl": {
                        "type": "array",
                        "items": {
                          "description": "List of permissions.",
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                            },
                            "who": {
                              "type": "object",
                              "properties": {
                                "_basetype": {
                                  "type": "string",
                                  "enum": [
                                    "user",
                                    "group"
                                  ]
                                },
                                "_owner": {
                                  "type": "boolean",
                                  "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                                },
                                "_pool_contact": {
                                  "type": "boolean",
                                  "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                                },
                                "user": {
                                  "type": "object",
                                  "properties": {
                                    "_id": {
                                      "type": "number",
                                      "format": "int64",
                                      "description": "The id of the user.\n"
                                    },
                                    "_version": {
                                      "type": "number",
                                      "readOnly": true,
                                      "format": "int64",
                                      "description": "The version of the user record.\n"
                                    },
                                    "type": {
                                      "type": "string",
                                      "readOnly": true,
                                      "enum": [
                                        "system",
                                        "easydb",
                                        "easydb_self_register",
                                        "anonymous",
                                        "collection",
                                        "email",
                                        "ldap",
                                        "sso"
                                      ]
                                    },
                                    "_generated_displayname": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                    },
                                    "login": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "Set for users of type `collection` or `email`.\n"
                                    },
                                    "frontend_language": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "The preferred frontend language of the user (BCP 47)\n"
                                    }
                                  }
                                },
                                "group": {
                                  "type": "object",
                                  "properties": {
                                    "_id": {
                                      "type": "number",
                                      "format": "int64",
                                      "description": "The id of the group.\n"
                                    },
                                    "_generated_displayname": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                    }
                                  }
                                }
                              }
                            },
                            "sticky": {
                              "type": "boolean",
                              "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                            },
                            "active": {
                              "type": "boolean",
                              "nullable": true,
                              "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                            },
                            "_right_preset": {
                              "type": "number",
                              "format": "int64",
                              "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                            },
                            "when": {
                              "type": "object",
                              "properties": {
                                "from": {
                                  "type": "string",
                                  "format": "iso8601_date",
                                  "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                                },
                                "to": {
                                  "type": "string",
                                  "format": "iso8601_date"
                                }
                              }
                            },
                            "rights": {
                              "description": "Object which carries the permissions granted by this item.\n",
                              "type": "object",
                              "additionalProperties": {
                                "type": "object",
                                "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                                "properties": {
                                  "_grantable": {
                                    "type": "boolean",
                                    "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                                  },
                                  "allow_update_and_remove": {
                                    "type": "boolean",
                                    "description": "Flag to allow to update or remove a file id from a column.\n"
                                  },
                                  "classes": {
                                    "type": "array",
                                    "description": "List of classes this permission if given for. An empty list matches all.\n",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "extensions": {
                                    "type": "array",
                                    "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "versions": {
                                    "type": "array",
                                    "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "limit": {
                                    "type": "string",
                                    "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                                  },
                                  "mask_ids": {
                                    "type": "object",
                                    "additionalProperties": {
                                      "description": "The key is the object type ID.\n",
                                      "type": "array",
                                      "items": {
                                        "oneOf": [
                                          {
                                            "type": "string",
                                            "description": "Set to `standard` for the standard mask.\n",
                                            "enum": [
                                              "standard"
                                            ]
                                          },
                                          {
                                            "type": "integer",
                                            "description": "The mask id given the permission for.\n",
                                            "minimum": 1
                                          }
                                        ]
                                      }
                                    }
                                  },
                                  "column_ids": {
                                    "description": "List of column api ids to apply this permission to.\n",
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    }
                                  },
                                  "objecttype_ids": {
                                    "description": "List of object type ids to apply this permission to.\n",
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    }
                                  },
                                  "pool_ids": {
                                    "description": "List of pool IDs to apply this permission to.\n",
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    }
                                  }
                                }
                              }
                            },
                            "tagfilter": {
                              "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                              "type": "object",
                              "properties": {
                                "any": {
                                  "type": "array",
                                  "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "all": {
                                  "type": "array",
                                  "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "not": {
                                  "type": "array",
                                  "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                                  "items": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "send_email_notification": {
                              "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                              "type": "object",
                              "properties": {
                                "text": {
                                  "description": "The text included in the email.\n",
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "_private_acl": {
                        "type": "boolean",
                        "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                      },
                      "_path": {
                        "type": "array",
                        "readOnly": true,
                        "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                        "items": {
                          "type": "object",
                          "properties": {
                            "_basetype": {
                              "type": "string",
                              "enum": [
                                "collection"
                              ]
                            },
                            "collection": {
                              "type": "object",
                              "properties": {
                                "_id": {
                                  "type": "integer"
                                },
                                "_id_parent": {
                                  "type": "integer"
                                },
                                "_version": {
                                  "type": "integer"
                                },
                                "displayname": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "_invalid_acl": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                      },
                      "_owner": {
                        "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                        "type": "object",
                        "properties": {
                          "_basetype": {
                            "type": "string",
                            "enum": [
                              "user",
                              "group"
                            ]
                          },
                          "_owner": {
                            "type": "boolean",
                            "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                          },
                          "_pool_contact": {
                            "type": "boolean",
                            "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                          },
                          "user": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "number",
                                "format": "int64",
                                "description": "The id of the user.\n"
                              },
                              "_version": {
                                "type": "number",
                                "readOnly": true,
                                "format": "int64",
                                "description": "The version of the user record.\n"
                              },
                              "type": {
                                "type": "string",
                                "readOnly": true,
                                "enum": [
                                  "system",
                                  "easydb",
                                  "easydb_self_register",
                                  "anonymous",
                                  "collection",
                                  "email",
                                  "ldap",
                                  "sso"
                                ]
                              },
                              "_generated_displayname": {
                                "type": "string",
                                "readOnly": true,
                                "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                              },
                              "login": {
                                "type": "string",
                                "readOnly": true,
                                "description": "Set for users of type `collection` or `email`.\n"
                              },
                              "frontend_language": {
                                "type": "string",
                                "readOnly": true,
                                "description": "The preferred frontend language of the user (BCP 47)\n"
                              }
                            }
                          },
                          "group": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "number",
                                "format": "int64",
                                "description": "The id of the group.\n"
                              },
                              "_generated_displayname": {
                                "type": "string",
                                "readOnly": true,
                                "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                              }
                            }
                          }
                        }
                      },
                      "objects": {
                        "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "_global_object_id": {
                              "type": "string",
                              "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                            },
                            "webfrontend_props": {
                              "type": "object",
                              "additionalProperties": true,
                              "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                            },
                            "lookup:_global_object_id": {
                              "type": "object",
                              "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                              "properties": {
                                "_allow_defer": {
                                  "type": "boolean"
                                },
                                "_objecttype": {
                                  "type": "string"
                                },
                                "_system_object_id": {
                                  "type": "integer"
                                },
                                "_uuid": {
                                  "type": "string"
                                },
                                "additionalProperties": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "_hotfolder_upload_urls": {
                        "description": "A list of URLs to upload files into this collection.\n",
                        "type": "array",
                        "readOnly": true,
                        "items": {
                          "type": "object",
                          "properties": {
                            "type": {
                              "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                              "type": "string",
                              "enum": [
                                "webdav",
                                "webdav-hotfolder"
                              ]
                            },
                            "url": {
                              "type": "string",
                              "format": "url"
                            }
                          }
                        }
                      },
                      "_has_pin": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                      },
                      "pin_ok": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                      },
                      "_created_at": {
                        "type": "string",
                        "format": "RFC3339_date",
                        "readOnly": true,
                        "description": "Timestamp when this collection was created.\n"
                      },
                      "_updated_at": {
                        "type": "string",
                        "format": "RFC3339_date",
                        "readOnly": true,
                        "description": "Timestamp when this collection was updated.\n"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required permission. See `code`\nfor the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create new collections.",
        "description": "* The user needs `BAG_CREATE` in the parent collection to create a collection.\n* The `_owner` needs to be the owner of the parent.\n* To set `_private_acl` or `_acl` the user needs `BAG_ACL`.\n* ACL items with `send_email_notification` will sent out and email.\n* `COLLECTION_INSERT` event is written.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "Allow storing the collection even if the owner doesn't have the necessary\npermissions for all objects to share the rights defined in the `_acl` property\nof the collection. The `_invalid_acl` flag will be set, if the user doesn't\nhave sufficient permissions to share all objects of the collection. The user\nneeds the permission `BAG_ACL` for the collection in order to use this\nparameter.\n\nDiffers from easydb 5: this confirmation is driven by the boolean\n`allow_invalid_acl` parameter. easydb 5 instead resolves the `202`\nconfirmation with a `collection_rights_policy` query parameter; there is no\n`allow_invalid_acl` parameter in easydb 5.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, the invalid-ACL validity check (whether the collection owner may\ngrant the rights of all linked objects) is not run inline. Instead a queued\n`ACTION_COLLECTION_ACL_CHECK` job is scheduled and the request returns\nimmediately, before the check has resolved.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "collection": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                        },
                        "_id_parent": {
                          "type": "number",
                          "format": "int64",
                          "minimum": 1,
                          "nullable": true,
                          "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                        },
                        "_version": {
                          "type": "number",
                          "format": "int64",
                          "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                        },
                        "children_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                        },
                        "objects_allowed": {
                          "type": "boolean",
                          "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                        },
                        "is_system_collection": {
                          "type": "boolean",
                          "readOnly": true,
                          "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "displayname": {
                          "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "description": {
                          "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                          "type": "object",
                          "properties": {
                            "de-DE": {
                              "type": "string"
                            },
                            "en-US": {
                              "type": "string"
                            }
                          },
                          "example": {
                            "de-DE": "Deutscher text",
                            "en-US": "English text"
                          }
                        },
                        "create_object": {
                          "nullable": true,
                          "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                          "type": "object",
                          "properties": {
                            "objecttype": {
                              "type": "string",
                              "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                            },
                            "mask_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                            },
                            "pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                            },
                            "linked_pool_id": {
                              "type": "integer",
                              "format": "int64",
                              "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                            },
                            "pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                            },
                            "linked_pool": {
                              "$ref": "#/components/schemas/PoolApi",
                              "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                            },
                            "eas_field": {
                              "type": "string",
                              "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                            },
                            "linked_object_pools": {
                              "type": "object",
                              "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            },
                            "hierarchy_linked_object": {
                              "type": "object",
                              "nullable": true,
                              "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                              "properties": {
                                "field": {
                                  "type": "string",
                                  "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                                }
                              }
                            },
                            "mapping": {
                              "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                              "oneOf": [
                                {
                                  "type": "string",
                                  "enum": [
                                    "standard",
                                    "none"
                                  ]
                                },
                                {
                                  "type": "integer",
                                  "format": "int64"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "mapping_recipe_configs": {
                              "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                              "allOf": [
                                {
                                  "type": "object",
                                  "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                  "additionalProperties": {
                                    "type": "object",
                                    "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                    "properties": {
                                      "params": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                        "example": {
                                          "size": 600,
                                          "format": "png",
                                          "resize_mode": "max",
                                          "jpegquality": 80,
                                          "strip": true
                                        }
                                      }
                                    },
                                    "example": {
                                      "imageconverter:browserthumbs": {
                                        "params": {
                                          "size": 1200,
                                          "format": "webp",
                                          "resize_mode": "max"
                                        }
                                      },
                                      "imageconverter:preview_pool_watermark": {
                                        "params": {
                                          "size": 600,
                                          "format": "jpg"
                                        }
                                      }
                                    }
                                  }
                                }
                              ]
                            },
                            "recognize_series": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                            },
                            "recognize_version": {
                              "type": "boolean",
                              "default": false,
                              "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                            },
                            "update_search_field": {
                              "type": "string",
                              "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                            },
                            "update_mode": {
                              "type": "string",
                              "default": "insert",
                              "enum": [
                                "insert",
                                "update",
                                "upsert"
                              ],
                              "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                            },
                            "update_policy": {
                              "type": "string",
                              "enum": [
                                "create_version",
                                "replace",
                                "create_version_preferred",
                                "refuse"
                              ],
                              "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                            },
                            "tags": {
                              "type": "array",
                              "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                              "items": {
                                "$ref": "#/components/schemas/Tag"
                              }
                            },
                            "plugin": {
                              "type": "string",
                              "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                              "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                            },
                            "plugin_config": {
                              "type": "object",
                              "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": true
                              }
                            }
                          }
                        },
                        "reference": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                        },
                        "shortname": {
                          "type": "string",
                          "nullable": true,
                          "description": "A unique string to set a collection shortname. This can be used for search.\n"
                        },
                        "type": {
                          "type": "string",
                          "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                        },
                        "pin_code": {
                          "type": "string",
                          "nullable": true,
                          "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                        },
                        "uuid": {
                          "type": "string",
                          "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                        },
                        "lookup:_id": {
                          "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        },
                        "lookup:_id_parent": {
                          "description": "The lookup to find the parent collection.\n",
                          "type": "object",
                          "properties": {
                            "reference": {
                              "type": "string",
                              "description": "The reference of the collection to lookup.\n"
                            }
                          }
                        }
                      }
                    },
                    "_basetype": {
                      "type": "string",
                      "enum": [
                        "collection"
                      ]
                    },
                    "_count": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection.\n"
                    },
                    "_count_recursive": {
                      "type": "number",
                      "format": "int64",
                      "readOnly": true,
                      "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                    },
                    "_create_object_compiled": {
                      "readOnly": true,
                      "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                      "type": "object",
                      "properties": {
                        "objecttype": {
                          "type": "string",
                          "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                        },
                        "mask_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                        },
                        "pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                        },
                        "linked_pool_id": {
                          "type": "integer",
                          "format": "int64",
                          "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                        },
                        "pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                        },
                        "linked_pool": {
                          "$ref": "#/components/schemas/PoolApi",
                          "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                        },
                        "eas_field": {
                          "type": "string",
                          "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                        },
                        "linked_object_pools": {
                          "type": "object",
                          "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "hierarchy_linked_object": {
                          "type": "object",
                          "nullable": true,
                          "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                          "properties": {
                            "field": {
                              "type": "string",
                              "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                            }
                          }
                        },
                        "mapping": {
                          "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                          "oneOf": [
                            {
                              "type": "string",
                              "enum": [
                                "standard",
                                "none"
                              ]
                            },
                            {
                              "type": "integer",
                              "format": "int64"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "mapping_recipe_configs": {
                          "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                          "allOf": [
                            {
                              "type": "object",
                              "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                              "additionalProperties": {
                                "type": "object",
                                "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                "properties": {
                                  "params": {
                                    "type": "object",
                                    "additionalProperties": true,
                                    "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                    "example": {
                                      "size": 600,
                                      "format": "png",
                                      "resize_mode": "max",
                                      "jpegquality": 80,
                                      "strip": true
                                    }
                                  }
                                },
                                "example": {
                                  "imageconverter:browserthumbs": {
                                    "params": {
                                      "size": 1200,
                                      "format": "webp",
                                      "resize_mode": "max"
                                    }
                                  },
                                  "imageconverter:preview_pool_watermark": {
                                    "params": {
                                      "size": 600,
                                      "format": "jpg"
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        },
                        "recognize_series": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                        },
                        "recognize_version": {
                          "type": "boolean",
                          "default": false,
                          "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                        },
                        "update_search_field": {
                          "type": "string",
                          "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                        },
                        "update_mode": {
                          "type": "string",
                          "default": "insert",
                          "enum": [
                            "insert",
                            "update",
                            "upsert"
                          ],
                          "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                        },
                        "update_policy": {
                          "type": "string",
                          "enum": [
                            "create_version",
                            "replace",
                            "create_version_preferred",
                            "refuse"
                          ],
                          "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                        },
                        "tags": {
                          "type": "array",
                          "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                          "items": {
                            "$ref": "#/components/schemas/Tag"
                          }
                        },
                        "plugin": {
                          "type": "string",
                          "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                          "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                        },
                        "plugin_config": {
                          "type": "object",
                          "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                          "additionalProperties": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        }
                      }
                    },
                    "_generated_rights": {
                      "type": "object",
                      "readOnly": true,
                      "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                      "properties": {
                        "create": {
                          "type": "object",
                          "properties": {}
                        },
                        "create_in_collection": {
                          "type": "object",
                          "properties": {}
                        },
                        "read": {
                          "type": "object",
                          "properties": {}
                        },
                        "write": {
                          "type": "object",
                          "properties": {}
                        },
                        "delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_upload": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_show": {
                          "type": "object",
                          "properties": {}
                        },
                        "asset_download": {
                          "type": "object",
                          "properties": {}
                        },
                        "mask": {
                          "type": "object",
                          "properties": {}
                        },
                        "link": {
                          "type": "object",
                          "properties": {}
                        },
                        "acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "change_owner": {
                          "type": "object",
                          "properties": {}
                        },
                        "unlink": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_read": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_write": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_acl": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_delete": {
                          "type": "object",
                          "properties": {}
                        },
                        "bag_create": {
                          "type": "object",
                          "properties": {}
                        },
                        "owner": {
                          "type": "object",
                          "properties": {}
                        }
                      }
                    },
                    "_has_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                    },
                    "_has_children": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                    },
                    "_has_remote_objects": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                    },
                    "_level": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                    },
                    "_acl": {
                      "type": "array",
                      "items": {
                        "description": "List of permissions.",
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                          },
                          "who": {
                            "type": "object",
                            "properties": {
                              "_basetype": {
                                "type": "string",
                                "enum": [
                                  "user",
                                  "group"
                                ]
                              },
                              "_owner": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                              },
                              "_pool_contact": {
                                "type": "boolean",
                                "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                              },
                              "user": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the user.\n"
                                  },
                                  "_version": {
                                    "type": "number",
                                    "readOnly": true,
                                    "format": "int64",
                                    "description": "The version of the user record.\n"
                                  },
                                  "type": {
                                    "type": "string",
                                    "readOnly": true,
                                    "enum": [
                                      "system",
                                      "easydb",
                                      "easydb_self_register",
                                      "anonymous",
                                      "collection",
                                      "email",
                                      "ldap",
                                      "sso"
                                    ]
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                  },
                                  "login": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "Set for users of type `collection` or `email`.\n"
                                  },
                                  "frontend_language": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "The preferred frontend language of the user (BCP 47)\n"
                                  }
                                }
                              },
                              "group": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "The id of the group.\n"
                                  },
                                  "_generated_displayname": {
                                    "type": "string",
                                    "readOnly": true,
                                    "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                  }
                                }
                              }
                            }
                          },
                          "sticky": {
                            "type": "boolean",
                            "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                          },
                          "active": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                          },
                          "_right_preset": {
                            "type": "number",
                            "format": "int64",
                            "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                          },
                          "when": {
                            "type": "object",
                            "properties": {
                              "from": {
                                "type": "string",
                                "format": "iso8601_date",
                                "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                              },
                              "to": {
                                "type": "string",
                                "format": "iso8601_date"
                              }
                            }
                          },
                          "rights": {
                            "description": "Object which carries the permissions granted by this item.\n",
                            "type": "object",
                            "additionalProperties": {
                              "type": "object",
                              "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                              "properties": {
                                "_grantable": {
                                  "type": "boolean",
                                  "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                                },
                                "allow_update_and_remove": {
                                  "type": "boolean",
                                  "description": "Flag to allow to update or remove a file id from a column.\n"
                                },
                                "classes": {
                                  "type": "array",
                                  "description": "List of classes this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "extensions": {
                                  "type": "array",
                                  "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "versions": {
                                  "type": "array",
                                  "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "limit": {
                                  "type": "string",
                                  "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                                },
                                "mask_ids": {
                                  "type": "object",
                                  "additionalProperties": {
                                    "description": "The key is the object type ID.\n",
                                    "type": "array",
                                    "items": {
                                      "oneOf": [
                                        {
                                          "type": "string",
                                          "description": "Set to `standard` for the standard mask.\n",
                                          "enum": [
                                            "standard"
                                          ]
                                        },
                                        {
                                          "type": "integer",
                                          "description": "The mask id given the permission for.\n",
                                          "minimum": 1
                                        }
                                      ]
                                    }
                                  }
                                },
                                "column_ids": {
                                  "description": "List of column api ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "objecttype_ids": {
                                  "description": "List of object type ids to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "pool_ids": {
                                  "description": "List of pool IDs to apply this permission to.\n",
                                  "type": "array",
                                  "items": {
                                    "type": "integer"
                                  }
                                }
                              }
                            }
                          },
                          "tagfilter": {
                            "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                            "type": "object",
                            "properties": {
                              "any": {
                                "type": "array",
                                "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "all": {
                                "type": "array",
                                "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              },
                              "not": {
                                "type": "array",
                                "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                                "items": {
                                  "type": "integer"
                                }
                              }
                            }
                          },
                          "send_email_notification": {
                            "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                            "type": "object",
                            "properties": {
                              "text": {
                                "description": "The text included in the email.\n",
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_private_acl": {
                      "type": "boolean",
                      "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                    },
                    "_path": {
                      "type": "array",
                      "readOnly": true,
                      "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_basetype": {
                            "type": "string",
                            "enum": [
                              "collection"
                            ]
                          },
                          "collection": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "integer"
                              },
                              "_id_parent": {
                                "type": "integer"
                              },
                              "_version": {
                                "type": "integer"
                              },
                              "displayname": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_invalid_acl": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                    },
                    "_owner": {
                      "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                      "type": "object",
                      "properties": {
                        "_basetype": {
                          "type": "string",
                          "enum": [
                            "user",
                            "group"
                          ]
                        },
                        "_owner": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                        },
                        "_pool_contact": {
                          "type": "boolean",
                          "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                        },
                        "user": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the user.\n"
                            },
                            "_version": {
                              "type": "number",
                              "readOnly": true,
                              "format": "int64",
                              "description": "The version of the user record.\n"
                            },
                            "type": {
                              "type": "string",
                              "readOnly": true,
                              "enum": [
                                "system",
                                "easydb",
                                "easydb_self_register",
                                "anonymous",
                                "collection",
                                "email",
                                "ldap",
                                "sso"
                              ]
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                            },
                            "login": {
                              "type": "string",
                              "readOnly": true,
                              "description": "Set for users of type `collection` or `email`.\n"
                            },
                            "frontend_language": {
                              "type": "string",
                              "readOnly": true,
                              "description": "The preferred frontend language of the user (BCP 47)\n"
                            }
                          }
                        },
                        "group": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "The id of the group.\n"
                            },
                            "_generated_displayname": {
                              "type": "string",
                              "readOnly": true,
                              "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                            }
                          }
                        }
                      }
                    },
                    "objects": {
                      "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_global_object_id": {
                            "type": "string",
                            "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                          },
                          "webfrontend_props": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                          },
                          "lookup:_global_object_id": {
                            "type": "object",
                            "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                            "properties": {
                              "_allow_defer": {
                                "type": "boolean"
                              },
                              "_objecttype": {
                                "type": "string"
                              },
                              "_system_object_id": {
                                "type": "integer"
                              },
                              "_uuid": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "_hotfolder_upload_urls": {
                      "description": "A list of URLs to upload files into this collection.\n",
                      "type": "array",
                      "readOnly": true,
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                            "type": "string",
                            "enum": [
                              "webdav",
                              "webdav-hotfolder"
                            ]
                          },
                          "url": {
                            "type": "string",
                            "format": "url"
                          }
                        }
                      }
                    },
                    "_has_pin": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                    },
                    "pin_ok": {
                      "type": "boolean",
                      "readOnly": true,
                      "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                    },
                    "_created_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was created.\n"
                    },
                    "_updated_at": {
                      "type": "string",
                      "format": "RFC3339_date",
                      "readOnly": true,
                      "description": "Timestamp when this collection was updated.\n"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The list of collections.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Array of collections.\n",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "collection": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "minimum": 1,
                            "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                          },
                          "_id_parent": {
                            "type": "number",
                            "format": "int64",
                            "minimum": 1,
                            "nullable": true,
                            "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                          },
                          "_version": {
                            "type": "number",
                            "format": "int64",
                            "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                          },
                          "children_allowed": {
                            "type": "boolean",
                            "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                          },
                          "objects_allowed": {
                            "type": "boolean",
                            "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                          },
                          "is_system_collection": {
                            "type": "boolean",
                            "readOnly": true,
                            "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                          },
                          "webfrontend_props": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                          },
                          "displayname": {
                            "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                            "type": "object",
                            "properties": {
                              "de-DE": {
                                "type": "string"
                              },
                              "en-US": {
                                "type": "string"
                              }
                            },
                            "example": {
                              "de-DE": "Deutscher text",
                              "en-US": "English text"
                            }
                          },
                          "description": {
                            "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                            "type": "object",
                            "properties": {
                              "de-DE": {
                                "type": "string"
                              },
                              "en-US": {
                                "type": "string"
                              }
                            },
                            "example": {
                              "de-DE": "Deutscher text",
                              "en-US": "English text"
                            }
                          },
                          "create_object": {
                            "nullable": true,
                            "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                            "type": "object",
                            "properties": {
                              "objecttype": {
                                "type": "string",
                                "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                              },
                              "mask_id": {
                                "type": "integer",
                                "format": "int64",
                                "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                              },
                              "pool_id": {
                                "type": "integer",
                                "format": "int64",
                                "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                              },
                              "linked_pool_id": {
                                "type": "integer",
                                "format": "int64",
                                "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                              },
                              "pool": {
                                "$ref": "#/components/schemas/PoolApi",
                                "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                              },
                              "linked_pool": {
                                "$ref": "#/components/schemas/PoolApi",
                                "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                              },
                              "eas_field": {
                                "type": "string",
                                "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                              },
                              "linked_object_pools": {
                                "type": "object",
                                "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "additionalProperties": true
                                }
                              },
                              "hierarchy_linked_object": {
                                "type": "object",
                                "nullable": true,
                                "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                                "properties": {
                                  "field": {
                                    "type": "string",
                                    "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                                  }
                                }
                              },
                              "mapping": {
                                "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                                "oneOf": [
                                  {
                                    "type": "string",
                                    "enum": [
                                      "standard",
                                      "none"
                                    ]
                                  },
                                  {
                                    "type": "integer",
                                    "format": "int64"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "mapping_recipe_configs": {
                                "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                                "allOf": [
                                  {
                                    "type": "object",
                                    "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                    "additionalProperties": {
                                      "type": "object",
                                      "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                      "properties": {
                                        "params": {
                                          "type": "object",
                                          "additionalProperties": true,
                                          "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                          "example": {
                                            "size": 600,
                                            "format": "png",
                                            "resize_mode": "max",
                                            "jpegquality": 80,
                                            "strip": true
                                          }
                                        }
                                      },
                                      "example": {
                                        "imageconverter:browserthumbs": {
                                          "params": {
                                            "size": 1200,
                                            "format": "webp",
                                            "resize_mode": "max"
                                          }
                                        },
                                        "imageconverter:preview_pool_watermark": {
                                          "params": {
                                            "size": 600,
                                            "format": "jpg"
                                          }
                                        }
                                      }
                                    }
                                  }
                                ]
                              },
                              "recognize_series": {
                                "type": "boolean",
                                "default": false,
                                "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                              },
                              "recognize_version": {
                                "type": "boolean",
                                "default": false,
                                "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                              },
                              "update_search_field": {
                                "type": "string",
                                "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                              },
                              "update_mode": {
                                "type": "string",
                                "default": "insert",
                                "enum": [
                                  "insert",
                                  "update",
                                  "upsert"
                                ],
                                "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                              },
                              "update_policy": {
                                "type": "string",
                                "enum": [
                                  "create_version",
                                  "replace",
                                  "create_version_preferred",
                                  "refuse"
                                ],
                                "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                              },
                              "tags": {
                                "type": "array",
                                "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                                "items": {
                                  "$ref": "#/components/schemas/Tag"
                                }
                              },
                              "plugin": {
                                "type": "string",
                                "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                                "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                              },
                              "plugin_config": {
                                "type": "object",
                                "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "additionalProperties": true
                                }
                              }
                            }
                          },
                          "reference": {
                            "type": "string",
                            "nullable": true,
                            "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                          },
                          "shortname": {
                            "type": "string",
                            "nullable": true,
                            "description": "A unique string to set a collection shortname. This can be used for search.\n"
                          },
                          "type": {
                            "type": "string",
                            "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                          },
                          "pin_code": {
                            "type": "string",
                            "nullable": true,
                            "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                          },
                          "uuid": {
                            "type": "string",
                            "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                          },
                          "lookup:_id": {
                            "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                            "type": "object",
                            "properties": {
                              "reference": {
                                "type": "string",
                                "description": "The reference of the collection to lookup.\n"
                              }
                            }
                          },
                          "lookup:_id_parent": {
                            "description": "The lookup to find the parent collection.\n",
                            "type": "object",
                            "properties": {
                              "reference": {
                                "type": "string",
                                "description": "The reference of the collection to lookup.\n"
                              }
                            }
                          }
                        }
                      },
                      "_basetype": {
                        "type": "string",
                        "enum": [
                          "collection"
                        ]
                      },
                      "_count": {
                        "type": "number",
                        "format": "int64",
                        "readOnly": true,
                        "description": "The number of objects in this collection.\n"
                      },
                      "_count_recursive": {
                        "type": "number",
                        "format": "int64",
                        "readOnly": true,
                        "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                      },
                      "_create_object_compiled": {
                        "readOnly": true,
                        "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                        "type": "object",
                        "properties": {
                          "objecttype": {
                            "type": "string",
                            "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                          },
                          "mask_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                          },
                          "pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                          },
                          "linked_pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                          },
                          "pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                          },
                          "linked_pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                          },
                          "eas_field": {
                            "type": "string",
                            "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                          },
                          "linked_object_pools": {
                            "type": "object",
                            "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "hierarchy_linked_object": {
                            "type": "object",
                            "nullable": true,
                            "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                            "properties": {
                              "field": {
                                "type": "string",
                                "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                              }
                            }
                          },
                          "mapping": {
                            "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                            "oneOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "standard",
                                  "none"
                                ]
                              },
                              {
                                "type": "integer",
                                "format": "int64"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "mapping_recipe_configs": {
                            "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                            "allOf": [
                              {
                                "type": "object",
                                "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                  "properties": {
                                    "params": {
                                      "type": "object",
                                      "additionalProperties": true,
                                      "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                      "example": {
                                        "size": 600,
                                        "format": "png",
                                        "resize_mode": "max",
                                        "jpegquality": 80,
                                        "strip": true
                                      }
                                    }
                                  },
                                  "example": {
                                    "imageconverter:browserthumbs": {
                                      "params": {
                                        "size": 1200,
                                        "format": "webp",
                                        "resize_mode": "max"
                                      }
                                    },
                                    "imageconverter:preview_pool_watermark": {
                                      "params": {
                                        "size": 600,
                                        "format": "jpg"
                                      }
                                    }
                                  }
                                }
                              }
                            ]
                          },
                          "recognize_series": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                          },
                          "recognize_version": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                          },
                          "update_search_field": {
                            "type": "string",
                            "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                          },
                          "update_mode": {
                            "type": "string",
                            "default": "insert",
                            "enum": [
                              "insert",
                              "update",
                              "upsert"
                            ],
                            "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                          },
                          "update_policy": {
                            "type": "string",
                            "enum": [
                              "create_version",
                              "replace",
                              "create_version_preferred",
                              "refuse"
                            ],
                            "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                          },
                          "tags": {
                            "type": "array",
                            "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                            "items": {
                              "$ref": "#/components/schemas/Tag"
                            }
                          },
                          "plugin": {
                            "type": "string",
                            "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                            "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                          },
                          "plugin_config": {
                            "type": "object",
                            "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          }
                        }
                      },
                      "_generated_rights": {
                        "type": "object",
                        "readOnly": true,
                        "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                        "properties": {
                          "create": {
                            "type": "object",
                            "properties": {}
                          },
                          "create_in_collection": {
                            "type": "object",
                            "properties": {}
                          },
                          "read": {
                            "type": "object",
                            "properties": {}
                          },
                          "write": {
                            "type": "object",
                            "properties": {}
                          },
                          "delete": {
                            "type": "object",
                            "properties": {}
                          },
                          "asset_upload": {
                            "type": "object",
                            "properties": {}
                          },
                          "asset_show": {
                            "type": "object",
                            "properties": {}
                          },
                          "asset_download": {
                            "type": "object",
                            "properties": {}
                          },
                          "mask": {
                            "type": "object",
                            "properties": {}
                          },
                          "link": {
                            "type": "object",
                            "properties": {}
                          },
                          "acl": {
                            "type": "object",
                            "properties": {}
                          },
                          "change_owner": {
                            "type": "object",
                            "properties": {}
                          },
                          "unlink": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_read": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_write": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_acl": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_delete": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_create": {
                            "type": "object",
                            "properties": {}
                          },
                          "owner": {
                            "type": "object",
                            "properties": {}
                          }
                        }
                      },
                      "_has_acl": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                      },
                      "_has_children": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                      },
                      "_has_remote_objects": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                      },
                      "_level": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                      },
                      "_acl": {
                        "type": "array",
                        "items": {
                          "description": "List of permissions.",
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                            },
                            "who": {
                              "type": "object",
                              "properties": {
                                "_basetype": {
                                  "type": "string",
                                  "enum": [
                                    "user",
                                    "group"
                                  ]
                                },
                                "_owner": {
                                  "type": "boolean",
                                  "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                                },
                                "_pool_contact": {
                                  "type": "boolean",
                                  "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                                },
                                "user": {
                                  "type": "object",
                                  "properties": {
                                    "_id": {
                                      "type": "number",
                                      "format": "int64",
                                      "description": "The id of the user.\n"
                                    },
                                    "_version": {
                                      "type": "number",
                                      "readOnly": true,
                                      "format": "int64",
                                      "description": "The version of the user record.\n"
                                    },
                                    "type": {
                                      "type": "string",
                                      "readOnly": true,
                                      "enum": [
                                        "system",
                                        "easydb",
                                        "easydb_self_register",
                                        "anonymous",
                                        "collection",
                                        "email",
                                        "ldap",
                                        "sso"
                                      ]
                                    },
                                    "_generated_displayname": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                    },
                                    "login": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "Set for users of type `collection` or `email`.\n"
                                    },
                                    "frontend_language": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "The preferred frontend language of the user (BCP 47)\n"
                                    }
                                  }
                                },
                                "group": {
                                  "type": "object",
                                  "properties": {
                                    "_id": {
                                      "type": "number",
                                      "format": "int64",
                                      "description": "The id of the group.\n"
                                    },
                                    "_generated_displayname": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                    }
                                  }
                                }
                              }
                            },
                            "sticky": {
                              "type": "boolean",
                              "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                            },
                            "active": {
                              "type": "boolean",
                              "nullable": true,
                              "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                            },
                            "_right_preset": {
                              "type": "number",
                              "format": "int64",
                              "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                            },
                            "when": {
                              "type": "object",
                              "properties": {
                                "from": {
                                  "type": "string",
                                  "format": "iso8601_date",
                                  "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                                },
                                "to": {
                                  "type": "string",
                                  "format": "iso8601_date"
                                }
                              }
                            },
                            "rights": {
                              "description": "Object which carries the permissions granted by this item.\n",
                              "type": "object",
                              "additionalProperties": {
                                "type": "object",
                                "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                                "properties": {
                                  "_grantable": {
                                    "type": "boolean",
                                    "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                                  },
                                  "allow_update_and_remove": {
                                    "type": "boolean",
                                    "description": "Flag to allow to update or remove a file id from a column.\n"
                                  },
                                  "classes": {
                                    "type": "array",
                                    "description": "List of classes this permission if given for. An empty list matches all.\n",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "extensions": {
                                    "type": "array",
                                    "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "versions": {
                                    "type": "array",
                                    "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "limit": {
                                    "type": "string",
                                    "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                                  },
                                  "mask_ids": {
                                    "type": "object",
                                    "additionalProperties": {
                                      "description": "The key is the object type ID.\n",
                                      "type": "array",
                                      "items": {
                                        "oneOf": [
                                          {
                                            "type": "string",
                                            "description": "Set to `standard` for the standard mask.\n",
                                            "enum": [
                                              "standard"
                                            ]
                                          },
                                          {
                                            "type": "integer",
                                            "description": "The mask id given the permission for.\n",
                                            "minimum": 1
                                          }
                                        ]
                                      }
                                    }
                                  },
                                  "column_ids": {
                                    "description": "List of column api ids to apply this permission to.\n",
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    }
                                  },
                                  "objecttype_ids": {
                                    "description": "List of object type ids to apply this permission to.\n",
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    }
                                  },
                                  "pool_ids": {
                                    "description": "List of pool IDs to apply this permission to.\n",
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    }
                                  }
                                }
                              }
                            },
                            "tagfilter": {
                              "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                              "type": "object",
                              "properties": {
                                "any": {
                                  "type": "array",
                                  "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "all": {
                                  "type": "array",
                                  "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "not": {
                                  "type": "array",
                                  "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                                  "items": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "send_email_notification": {
                              "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                              "type": "object",
                              "properties": {
                                "text": {
                                  "description": "The text included in the email.\n",
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "_private_acl": {
                        "type": "boolean",
                        "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                      },
                      "_path": {
                        "type": "array",
                        "readOnly": true,
                        "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                        "items": {
                          "type": "object",
                          "properties": {
                            "_basetype": {
                              "type": "string",
                              "enum": [
                                "collection"
                              ]
                            },
                            "collection": {
                              "type": "object",
                              "properties": {
                                "_id": {
                                  "type": "integer"
                                },
                                "_id_parent": {
                                  "type": "integer"
                                },
                                "_version": {
                                  "type": "integer"
                                },
                                "displayname": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "_invalid_acl": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                      },
                      "_owner": {
                        "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                        "type": "object",
                        "properties": {
                          "_basetype": {
                            "type": "string",
                            "enum": [
                              "user",
                              "group"
                            ]
                          },
                          "_owner": {
                            "type": "boolean",
                            "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                          },
                          "_pool_contact": {
                            "type": "boolean",
                            "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                          },
                          "user": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "number",
                                "format": "int64",
                                "description": "The id of the user.\n"
                              },
                              "_version": {
                                "type": "number",
                                "readOnly": true,
                                "format": "int64",
                                "description": "The version of the user record.\n"
                              },
                              "type": {
                                "type": "string",
                                "readOnly": true,
                                "enum": [
                                  "system",
                                  "easydb",
                                  "easydb_self_register",
                                  "anonymous",
                                  "collection",
                                  "email",
                                  "ldap",
                                  "sso"
                                ]
                              },
                              "_generated_displayname": {
                                "type": "string",
                                "readOnly": true,
                                "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                              },
                              "login": {
                                "type": "string",
                                "readOnly": true,
                                "description": "Set for users of type `collection` or `email`.\n"
                              },
                              "frontend_language": {
                                "type": "string",
                                "readOnly": true,
                                "description": "The preferred frontend language of the user (BCP 47)\n"
                              }
                            }
                          },
                          "group": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "number",
                                "format": "int64",
                                "description": "The id of the group.\n"
                              },
                              "_generated_displayname": {
                                "type": "string",
                                "readOnly": true,
                                "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                              }
                            }
                          }
                        }
                      },
                      "objects": {
                        "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "_global_object_id": {
                              "type": "string",
                              "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                            },
                            "webfrontend_props": {
                              "type": "object",
                              "additionalProperties": true,
                              "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                            },
                            "lookup:_global_object_id": {
                              "type": "object",
                              "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                              "properties": {
                                "_allow_defer": {
                                  "type": "boolean"
                                },
                                "_objecttype": {
                                  "type": "string"
                                },
                                "_system_object_id": {
                                  "type": "integer"
                                },
                                "_uuid": {
                                  "type": "string"
                                },
                                "additionalProperties": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "_hotfolder_upload_urls": {
                        "description": "A list of URLs to upload files into this collection.\n",
                        "type": "array",
                        "readOnly": true,
                        "items": {
                          "type": "object",
                          "properties": {
                            "type": {
                              "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                              "type": "string",
                              "enum": [
                                "webdav",
                                "webdav-hotfolder"
                              ]
                            },
                            "url": {
                              "type": "string",
                              "format": "url"
                            }
                          }
                        }
                      },
                      "_has_pin": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                      },
                      "pin_ok": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                      },
                      "_created_at": {
                        "type": "string",
                        "format": "RFC3339_date",
                        "readOnly": true,
                        "description": "Timestamp when this collection was created.\n"
                      },
                      "_updated_at": {
                        "type": "string",
                        "format": "RFC3339_date",
                        "readOnly": true,
                        "description": "Timestamp when this collection was updated.\n"
                      }
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The owner of one of the created collections lacks a grantable right\nfor a linked object and the caller has `BAG_ACL`. Re-send with\n`allow_invalid_acl=true` to store with sharing disabled.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionRemoveNotAllObjectsFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required permission. See `code`\nfor the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/collection/list/{parentId}": {
      "x-path": "/collection/list",
      "description": "Retrieve the immediate children of the collection identified by\n`parentId`. Only collections the user has `BAG_READ` for are returned.\n",
      "get": {
        "summary": "Retrieve all children of the given parent collection. This returns only the immediate children.",
        "description": "* Requires an authenticated user.\n* Only collections the user has `BAG_READ` permissions for are returned.\n* This call is slow for non-root users if there are many collections in the system.\n",
        "parameters": [
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "The offset when requesting the collection list."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "The limit when requesting the collection list. Default is _1000_."
          },
          {
            "name": "parentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The parent id of the collection to list the children for. Use `null` to\nretrieve collections without parent."
          },
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The list of collections.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Array of collections.\n",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "collection": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "number",
                            "format": "int64",
                            "minimum": 1,
                            "description": "The `_id` is issued from the fylr \"sequence\" table when a collection is created.\n"
                          },
                          "_id_parent": {
                            "type": "number",
                            "format": "int64",
                            "minimum": 1,
                            "nullable": true,
                            "description": "The `_id_parent` can be set to link a collection as sub collection to\nanother. The `_owner` if a child collection will always be set to the\nowner of the parent collection.\n"
                          },
                          "_version": {
                            "type": "number",
                            "format": "int64",
                            "description": "The `_version` of the collection created or updated. New collections\nmust be inserted using version _1_. Version updates must provide the\ncurrent version + 1. The server rejects updates / insert if the\nversion doesn't match the expected version.\n"
                          },
                          "children_allowed": {
                            "type": "boolean",
                            "description": "Flag to indicate if this collection can have children or not. This\nis to keep compability with easydb 5 and has no effect in **fylr**.\n"
                          },
                          "objects_allowed": {
                            "type": "boolean",
                            "description": "Flag to indicate if this collection can have link objects or not.\nThis is to keep compability with easydb 5 and has no effect in\n**fylr**.\n"
                          },
                          "is_system_collection": {
                            "type": "boolean",
                            "readOnly": true,
                            "description": "Flag to inidicate that this collection is a system collection. A\nsystem collection cannot be deleted.\n"
                          },
                          "webfrontend_props": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                          },
                          "displayname": {
                            "description": "The displayname of the collection is used as primary label for the user when this collection is displayed.\n",
                            "type": "object",
                            "properties": {
                              "de-DE": {
                                "type": "string"
                              },
                              "en-US": {
                                "type": "string"
                              }
                            },
                            "example": {
                              "de-DE": "Deutscher text",
                              "en-US": "English text"
                            }
                          },
                          "description": {
                            "description": "The description of the collection is used as a more detail information block when presenting the collection.\n",
                            "type": "object",
                            "properties": {
                              "de-DE": {
                                "type": "string"
                              },
                              "en-US": {
                                "type": "string"
                              }
                            },
                            "example": {
                              "de-DE": "Deutscher text",
                              "en-US": "English text"
                            }
                          },
                          "create_object": {
                            "nullable": true,
                            "description": "If the collection is used to create objects, like with `/api/db?collection=ID` or via WebDAV, the objects need some\nbasic information so the records can be created. This object defines these basics. The `_compiled_created_object`\ncan be used to access the information from the first parent which has this property set. There is no possibility to\nremove this setting on a lower level once the parent collection has set it.\n",
                            "type": "object",
                            "properties": {
                              "objecttype": {
                                "type": "string",
                                "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                              },
                              "mask_id": {
                                "type": "integer",
                                "format": "int64",
                                "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                              },
                              "pool_id": {
                                "type": "integer",
                                "format": "int64",
                                "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                              },
                              "linked_pool_id": {
                                "type": "integer",
                                "format": "int64",
                                "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                              },
                              "pool": {
                                "$ref": "#/components/schemas/PoolApi",
                                "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                              },
                              "linked_pool": {
                                "$ref": "#/components/schemas/PoolApi",
                                "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                              },
                              "eas_field": {
                                "type": "string",
                                "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                              },
                              "linked_object_pools": {
                                "type": "object",
                                "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "additionalProperties": true
                                }
                              },
                              "hierarchy_linked_object": {
                                "type": "object",
                                "nullable": true,
                                "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                                "properties": {
                                  "field": {
                                    "type": "string",
                                    "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                                  }
                                }
                              },
                              "mapping": {
                                "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                                "oneOf": [
                                  {
                                    "type": "string",
                                    "enum": [
                                      "standard",
                                      "none"
                                    ]
                                  },
                                  {
                                    "type": "integer",
                                    "format": "int64"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "mapping_recipe_configs": {
                                "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                                "allOf": [
                                  {
                                    "type": "object",
                                    "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                    "additionalProperties": {
                                      "type": "object",
                                      "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                      "properties": {
                                        "params": {
                                          "type": "object",
                                          "additionalProperties": true,
                                          "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                          "example": {
                                            "size": 600,
                                            "format": "png",
                                            "resize_mode": "max",
                                            "jpegquality": 80,
                                            "strip": true
                                          }
                                        }
                                      },
                                      "example": {
                                        "imageconverter:browserthumbs": {
                                          "params": {
                                            "size": 1200,
                                            "format": "webp",
                                            "resize_mode": "max"
                                          }
                                        },
                                        "imageconverter:preview_pool_watermark": {
                                          "params": {
                                            "size": 600,
                                            "format": "jpg"
                                          }
                                        }
                                      }
                                    }
                                  }
                                ]
                              },
                              "recognize_series": {
                                "type": "boolean",
                                "default": false,
                                "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                              },
                              "recognize_version": {
                                "type": "boolean",
                                "default": false,
                                "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                              },
                              "update_search_field": {
                                "type": "string",
                                "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                              },
                              "update_mode": {
                                "type": "string",
                                "default": "insert",
                                "enum": [
                                  "insert",
                                  "update",
                                  "upsert"
                                ],
                                "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                              },
                              "update_policy": {
                                "type": "string",
                                "enum": [
                                  "create_version",
                                  "replace",
                                  "create_version_preferred",
                                  "refuse"
                                ],
                                "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                              },
                              "tags": {
                                "type": "array",
                                "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                                "items": {
                                  "$ref": "#/components/schemas/Tag"
                                }
                              },
                              "plugin": {
                                "type": "string",
                                "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                                "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                              },
                              "plugin_config": {
                                "type": "object",
                                "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "additionalProperties": true
                                }
                              }
                            }
                          },
                          "reference": {
                            "type": "string",
                            "nullable": true,
                            "description": "A unique string to set a collection reference. This can be used in collection lookups and in the search. The\nserver will create a root rollection with the reference `system:root`. Underneath the root collection, each user\ngets a top level collection for his collection. This will have a reference starting with `user:ref:\u003clogin|reference\u003e`.\n"
                          },
                          "shortname": {
                            "type": "string",
                            "nullable": true,
                            "description": "A unique string to set a collection shortname. This can be used for search.\n"
                          },
                          "type": {
                            "type": "string",
                            "description": "Usually set to `workfolder` or `search`, this property has currently no effect in **fylr**. Only for the backup,\n`search` is used to replace ids in saved searches.\n"
                          },
                          "pin_code": {
                            "type": "string",
                            "nullable": true,
                            "description": "For sharing, a collection can be protected with a pin code. This pin code must be entered by the user and saved\nvia `/api/user` in order to access the objects in the collection.\n"
                          },
                          "uuid": {
                            "type": "string",
                            "description": "A unique ID for the collection. This can be set for new collections or will be assigned by the server.\nThe UUID of the collection to access it via WebDAV.\n"
                          },
                          "lookup:_id": {
                            "description": "The lookup can be used to find collections by reference. When this is used the `_version` is automatically\nset to the current version + 1.\n",
                            "type": "object",
                            "properties": {
                              "reference": {
                                "type": "string",
                                "description": "The reference of the collection to lookup.\n"
                              }
                            }
                          },
                          "lookup:_id_parent": {
                            "description": "The lookup to find the parent collection.\n",
                            "type": "object",
                            "properties": {
                              "reference": {
                                "type": "string",
                                "description": "The reference of the collection to lookup.\n"
                              }
                            }
                          }
                        }
                      },
                      "_basetype": {
                        "type": "string",
                        "enum": [
                          "collection"
                        ]
                      },
                      "_count": {
                        "type": "number",
                        "format": "int64",
                        "readOnly": true,
                        "description": "The number of objects in this collection.\n"
                      },
                      "_count_recursive": {
                        "type": "number",
                        "format": "int64",
                        "readOnly": true,
                        "description": "The number of objects in this collection and and all descendant collections (recursive).\n"
                      },
                      "_create_object_compiled": {
                        "readOnly": true,
                        "description": "The `collection.create_object` setting for this collection (if set) or the first parent collection which has it.`\n",
                        "type": "object",
                        "properties": {
                          "objecttype": {
                            "type": "string",
                            "description": "Technical name of the target objecttype the pipeline writes into.\nMust reference an existing objecttype (resolved via\n`datamodel.TableByName`); an unknown name fails with\n\"Objecttype not found\". De-facto required: an empty value disables the\nentire create-object rule (ApiToObject returns nil, nil).\n"
                          },
                          "mask_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "API id of the mask, scoped to `objecttype`, through which the\nnew/updated object is written. Must be an existing mask api-id on that\nobjecttype, otherwise: \"Mask \u003cid\u003e not found in objecttype \u003cname\u003e\".\n"
                          },
                          "pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool the main object is filed into. Required only when the\nresolved `eas_field` path crosses a pool-managed objecttype; supplying\nit when not needed fails with \"Pool not needed for \u003cfield\u003e\", omitting it\nwhen needed fails with \"Pool required for \u003cfield\u003e\".\n"
                          },
                          "linked_pool_id": {
                            "type": "integer",
                            "format": "int64",
                            "description": "Optional. Pool for an asset that lives inside a linked object. Allowed\nonly when `eas_field` is inside a link mask and that linked objecttype\nis pool-managed; otherwise rejected.\n"
                          },
                          "pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Full pool descriptor — only used by the backup / restore pipeline so it\ncan recreate a referenced pool that doesn't exist on the target\ninstance. Regular callers should set `pool_id` and leave this empty.\n"
                          },
                          "linked_pool": {
                            "$ref": "#/components/schemas/PoolApi",
                            "description": "Same as `pool` but for the linked-object pool — only used by\nbackup / restore.\n"
                          },
                          "eas_field": {
                            "type": "string",
                            "description": "Full API name (relative to `objecttype`; the `\u003cobjecttype\u003e.` prefix is\nadded internally) of the field that receives the uploaded asset. The\nreferenced column MUST be of type `files`, otherwise:\n'eas_field \u003cname\u003e needs to be type \"file\" but is \u003ctype\u003e'. An unknown\nfield fails with 'eas_field \u003cname\u003e not found in objecttype \u003cname\u003e'.\nLinked-object fields are allowed. Optional for rules that attach no\nfile; when set it also drives pool-requirement detection and the\n`update_policy` nesting check.\n"
                          },
                          "linked_object_pools": {
                            "type": "object",
                            "description": "Per-pool overrides for linked-object pools, keyed by the linked\nobject's field API name (without the objecttype prefix, added\ninternally). Each key must resolve to a link column whose target table\nis pool-managed; otherwise \"linked_object_field \u003cname\u003e not found\" or\n\"has no pool management\". Each value is the abbreviated pool descriptor\n(id, name, path).\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "hierarchy_linked_object": {
                            "type": "object",
                            "nullable": true,
                            "description": "Optional. Fills a linked-object field with hierarchy data. May be null.\n",
                            "properties": {
                              "field": {
                                "type": "string",
                                "description": "Full API name of the linked-object field to fill. Constraints\n(enforced in Init): the field must exist with a column, the column\nmust be a text type, the target objecttype must be hierarchical, the\nfield must not be inside a reverse-nested structure, and its link\nparent path may be at most depth 2 (no deep nesting).\n"
                              }
                            }
                          },
                          "mapping": {
                            "description": "Selects the field mapping used to interpret incoming file metadata.\nAccepted: the string `standard` (built-in standard mapping), the string\n`none` (no mapping), an integer mapping id, or null/absent (no mapping).\nAny other value: 'Mapping \"\u003cv\u003e\" not accepted. Allowed: \"standard\",\n\"none\", \u003cmapping-id\u003e'.\n",
                            "oneOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "standard",
                                  "none"
                                ]
                              },
                              {
                                "type": "integer",
                                "format": "int64"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "mapping_recipe_configs": {
                            "description": "Per-recipe configuration overrides. Allowed ONLY when `mapping` is a\nspecific integer mapping id; setting it otherwise fails with\n\"mapping recipe configs can only be set for a specific mapping\".\n(Go json key is `mapping_recipe_configs`, plural.)\n",
                            "allOf": [
                              {
                                "type": "object",
                                "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
                                "additionalProperties": {
                                  "type": "object",
                                  "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
                                  "properties": {
                                    "params": {
                                      "type": "object",
                                      "additionalProperties": true,
                                      "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
                                      "example": {
                                        "size": 600,
                                        "format": "png",
                                        "resize_mode": "max",
                                        "jpegquality": 80,
                                        "strip": true
                                      }
                                    }
                                  },
                                  "example": {
                                    "imageconverter:browserthumbs": {
                                      "params": {
                                        "size": 1200,
                                        "format": "webp",
                                        "resize_mode": "max"
                                      }
                                    },
                                    "imageconverter:preview_pool_watermark": {
                                      "params": {
                                        "size": 600,
                                        "format": "jpg"
                                      }
                                    }
                                  }
                                }
                              }
                            ]
                          },
                          "recognize_series": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to group related incoming files into a\nseries. Default false.\n"
                          },
                          "recognize_version": {
                            "type": "boolean",
                            "default": false,
                            "description": "When true, the pipeline attempts to detect that an incoming file is a\nnew version of an existing asset. Default false.\n"
                          },
                          "update_search_field": {
                            "type": "string",
                            "description": "Optional. Full API name of the field used to look up an existing object\nwhen `update_mode` is `update` or `upsert` (ignored for `insert`). Must\nbe a lookup-supported field or the literal `_global_object_id`; fields\ninside a reverse-nested structure are rejected.\n"
                          },
                          "update_mode": {
                            "type": "string",
                            "default": "insert",
                            "enum": [
                              "insert",
                              "update",
                              "upsert"
                            ],
                            "description": "Whether each processed file CREATES a new object or UPDATES an existing\none. Empty/absent is normalized to `insert`; any value outside the enum\nfails with \"Unknown update mode \u003cmode\u003e\".\n  - `insert`: always create a brand-new object; no existing-object\n    lookup. `update_search_field` is ignored and `update_policy` is\n    forced to empty.\n  - `update`: locate an existing object via `update_search_field` and\n    update it; does not create when none is found.\n  - `upsert`: locate an existing object and update it, otherwise insert\n    a new one.\nFor `update`/`upsert`, `update_policy` resolves an asset collision on\n`eas_field`.\n"
                          },
                          "update_policy": {
                            "type": "string",
                            "enum": [
                              "create_version",
                              "replace",
                              "create_version_preferred",
                              "refuse"
                            ],
                            "description": "How to resolve the uploaded asset against an EXISTING asset in\n`eas_field` when `update_mode` is `update` or `upsert`. An unknown value\nfails with \"Unknown update policy \u003cpolicy\u003e\".\n  - `create_version`: add the new file as a new version of the existing\n    asset.\n  - `replace`: overwrite the existing asset with the new file.\n  - `create_version_preferred`: add as a new version and mark it the\n    preferred one.\n  - `refuse`: reject the collision; do not write.\nMode-dependent normalization:\n  - `update_mode=insert`: this field is ignored and forced to empty;\n    only the four values above (or empty) are accepted as input.\n  - `update`/`upsert` with `eas_field` inside a NESTED field: forced to\n    `create_version` (only create_version is meaningful for nested file\n    fields).\n  - `update`/`upsert`, non-nested: one of the four enum values is\n    required (empty is NOT accepted).\n"
                          },
                          "tags": {
                            "type": "array",
                            "description": "Tags to set for the created main object. The object also receives all\ndefault tags with display type \"hidden\". Created linked objects get the\ndefault tags only, not these configured ones.\n",
                            "items": {
                              "$ref": "#/components/schemas/Tag"
                            }
                          },
                          "plugin": {
                            "type": "string",
                            "pattern": "^(.+?):([a-z][a-z_0-9]+)$",
                            "description": "Optional. Plugin callback that post-processes each uploaded file, in the\nstrict format `\u003cpluginName\u003e:\u003ccallbackName\u003e` (the colon and callback are\nmandatory). `callbackName` must start with a lowercase letter and use\nonly `[a-z_0-9]`. The plugin must exist and declare a `collection_upload`\ncallback of that name in its manifest; otherwise the request fails\n(wrong format / unknown plugin / plugin not found / unknown\ncollection_upload). Example: `fylr_example:filename_copy`.\n"
                          },
                          "plugin_config": {
                            "type": "object",
                            "description": "Optional, plugin-specific configuration passed through to the named\n`plugin` callback. Opaque to the collection pipeline: it is typed only as\na nested map `{ \u003cconfigName\u003e: { \u003cparamName\u003e: \u003cvalue\u003e } }` and is NOT\ninterpreted by core. Keys and value schemas are defined by the chosen\nplugin's `collection_upload` config section in its manifest; unknown\nconfig names or parameters are warn-logged and IGNORED (not rejected),\nand parameter values are validated only by the plugin's own param types.\nIt is free-form here because the valid keys depend entirely on the\nplugin manifest — consult that plugin's documentation. Only meaningful\nwhen `plugin` is set.\n",
                            "additionalProperties": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          }
                        }
                      },
                      "_generated_rights": {
                        "type": "object",
                        "readOnly": true,
                        "description": "Object which lists the compiled permissions for the current user. Not all permissions are present in all contexts.\n",
                        "properties": {
                          "create": {
                            "type": "object",
                            "properties": {}
                          },
                          "create_in_collection": {
                            "type": "object",
                            "properties": {}
                          },
                          "read": {
                            "type": "object",
                            "properties": {}
                          },
                          "write": {
                            "type": "object",
                            "properties": {}
                          },
                          "delete": {
                            "type": "object",
                            "properties": {}
                          },
                          "asset_upload": {
                            "type": "object",
                            "properties": {}
                          },
                          "asset_show": {
                            "type": "object",
                            "properties": {}
                          },
                          "asset_download": {
                            "type": "object",
                            "properties": {}
                          },
                          "mask": {
                            "type": "object",
                            "properties": {}
                          },
                          "link": {
                            "type": "object",
                            "properties": {}
                          },
                          "acl": {
                            "type": "object",
                            "properties": {}
                          },
                          "change_owner": {
                            "type": "object",
                            "properties": {}
                          },
                          "unlink": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_read": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_write": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_acl": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_delete": {
                            "type": "object",
                            "properties": {}
                          },
                          "bag_create": {
                            "type": "object",
                            "properties": {}
                          },
                          "owner": {
                            "type": "object",
                            "properties": {}
                          }
                        }
                      },
                      "_has_acl": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag that indicates that this collection has an active `_acl` (even if inherited).\n"
                      },
                      "_has_children": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag that inidicates if this collection has children. This flag is indpendent of the actual permissions of\nthe user for that collection. So, if the user cannot access the only sub collection of this collection, the\n`_has_children` flag will still be set.\n"
                      },
                      "_has_remote_objects": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag that inidicates if this collection contains at least one foreign collection object.\n"
                      },
                      "_level": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Starting with 1, `_level` states the depth of the collection in the collection tree. The top level from the user's\nperspective is 3. The 1st level is the root collection, the 2nd level the user's top level collection which is a system\ncollection and automatically created to hold all the user's collections underneath.\n"
                      },
                      "_acl": {
                        "type": "array",
                        "items": {
                          "description": "List of permissions.",
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "number",
                              "format": "int64",
                              "description": "Auto assigned `_id` to indicate the permission. Permissions can be\nupdated by re-using the `_id`.\n"
                            },
                            "who": {
                              "type": "object",
                              "properties": {
                                "_basetype": {
                                  "type": "string",
                                  "enum": [
                                    "user",
                                    "group"
                                  ]
                                },
                                "_owner": {
                                  "type": "boolean",
                                  "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                                },
                                "_pool_contact": {
                                  "type": "boolean",
                                  "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                                },
                                "user": {
                                  "type": "object",
                                  "properties": {
                                    "_id": {
                                      "type": "number",
                                      "format": "int64",
                                      "description": "The id of the user.\n"
                                    },
                                    "_version": {
                                      "type": "number",
                                      "readOnly": true,
                                      "format": "int64",
                                      "description": "The version of the user record.\n"
                                    },
                                    "type": {
                                      "type": "string",
                                      "readOnly": true,
                                      "enum": [
                                        "system",
                                        "easydb",
                                        "easydb_self_register",
                                        "anonymous",
                                        "collection",
                                        "email",
                                        "ldap",
                                        "sso"
                                      ]
                                    },
                                    "_generated_displayname": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                                    },
                                    "login": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "Set for users of type `collection` or `email`.\n"
                                    },
                                    "frontend_language": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "The preferred frontend language of the user (BCP 47)\n"
                                    }
                                  }
                                },
                                "group": {
                                  "type": "object",
                                  "properties": {
                                    "_id": {
                                      "type": "number",
                                      "format": "int64",
                                      "description": "The id of the group.\n"
                                    },
                                    "_generated_displayname": {
                                      "type": "string",
                                      "readOnly": true,
                                      "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                                    }
                                  }
                                }
                              }
                            },
                            "sticky": {
                              "type": "boolean",
                              "description": "Flag to indicate that this permission persist even if subordinate\npermissions use the `_private_acl` flag to clear the list of permissions\ninherited from their parent. This is useful to add permissions which\ncannot be taken away from sub collections.\n"
                            },
                            "active": {
                              "type": "boolean",
                              "nullable": true,
                              "description": "Flag to indicate if this permission is active. It can be used to\ntemporarily disable permissions without losing details of the\npermission.\n"
                            },
                            "_right_preset": {
                              "type": "number",
                              "format": "int64",
                              "description": "The preset used for this permission. If set, no permissions need to be\nset in this entry, permissions are taken from the given preset.\n"
                            },
                            "when": {
                              "type": "object",
                              "properties": {
                                "from": {
                                  "type": "string",
                                  "format": "iso8601_date",
                                  "description": "If set, the permission is only valid from this date on. It can be\ngiven in ISO 8601 format, so e.g. \"2025\" sets the beginning of the\nyear 2025. Dates are parsed as UTC if not specified with time zone.\n"
                                },
                                "to": {
                                  "type": "string",
                                  "format": "iso8601_date"
                                }
                              }
                            },
                            "rights": {
                              "description": "Object which carries the permissions granted by this item.\n",
                              "type": "object",
                              "additionalProperties": {
                                "type": "object",
                                "description": "Depending on the context, only some properties can be used to define a right. The key is the name of permission.\n",
                                "properties": {
                                  "_grantable": {
                                    "type": "boolean",
                                    "description": "Flag to indicate that this permission can be shared in a collection ACL.\n"
                                  },
                                  "allow_update_and_remove": {
                                    "type": "boolean",
                                    "description": "Flag to allow to update or remove a file id from a column.\n"
                                  },
                                  "classes": {
                                    "type": "array",
                                    "description": "List of classes this permission if given for. An empty list matches all.\n",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "extensions": {
                                    "type": "array",
                                    "description": "List of extensions this permission if given for. An empty list matches all.\n",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "versions": {
                                    "type": "array",
                                    "description": "List of version names (renditions) this permission if given for. An empty list matches all.\n",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "limit": {
                                    "type": "string",
                                    "description": "Byte size as string. For formats refer to (go-datasize](https://github.com/programmfabrik/go-datasize).\n"
                                  },
                                  "mask_ids": {
                                    "type": "object",
                                    "additionalProperties": {
                                      "description": "The key is the object type ID.\n",
                                      "type": "array",
                                      "items": {
                                        "oneOf": [
                                          {
                                            "type": "string",
                                            "description": "Set to `standard` for the standard mask.\n",
                                            "enum": [
                                              "standard"
                                            ]
                                          },
                                          {
                                            "type": "integer",
                                            "description": "The mask id given the permission for.\n",
                                            "minimum": 1
                                          }
                                        ]
                                      }
                                    }
                                  },
                                  "column_ids": {
                                    "description": "List of column api ids to apply this permission to.\n",
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    }
                                  },
                                  "objecttype_ids": {
                                    "description": "List of object type ids to apply this permission to.\n",
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    }
                                  },
                                  "pool_ids": {
                                    "description": "List of pool IDs to apply this permission to.\n",
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    }
                                  }
                                }
                              }
                            },
                            "tagfilter": {
                              "description": "The permission can be filtered by tags. Depending on the context, the\ntags of an object influence the permission. `any`, `all` and `not` are\nmatched in an `AND` fashion.\n",
                              "type": "object",
                              "properties": {
                                "any": {
                                  "type": "array",
                                  "description": "List of tag ids. Any one of the tags must set to match this condition.\n",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "all": {
                                  "type": "array",
                                  "description": "List of tag ids. All of the tags must be set to match this condition.\n",
                                  "items": {
                                    "type": "integer"
                                  }
                                },
                                "not": {
                                  "type": "array",
                                  "description": "List of tag ids. None of the tags must be set to match this condition.\n",
                                  "items": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "send_email_notification": {
                              "description": "If set and newly created, this write-only property is used to send an\nemail with sharing information to all users of this ACL item.\n",
                              "type": "object",
                              "properties": {
                                "text": {
                                  "description": "The text included in the email.\n",
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "_private_acl": {
                        "type": "boolean",
                        "description": "Flag which indicates a private ACL. With this setting ACL from the parent are ignored (except for the items\nwhich set `sticky`.\n"
                      },
                      "_path": {
                        "type": "array",
                        "readOnly": true,
                        "description": "Array of parent collections. A minimal record is available for all parent collections. This includes collections\nthe user has not direct permission to access. Frontends can use the path to build a tree view of all collections.\n",
                        "items": {
                          "type": "object",
                          "properties": {
                            "_basetype": {
                              "type": "string",
                              "enum": [
                                "collection"
                              ]
                            },
                            "collection": {
                              "type": "object",
                              "properties": {
                                "_id": {
                                  "type": "integer"
                                },
                                "_id_parent": {
                                  "type": "integer"
                                },
                                "_version": {
                                  "type": "integer"
                                },
                                "displayname": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "_invalid_acl": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Collection can share permissions to other users. The owner of the\ncollection must carry the grantable permission for each object in the\ncollection in order to share the collection. **fylr** determines for the\nwhole collection if sharing is allowed or not. If it is not allowed, the\ncollection will be put in `_invalid_acl: true` state which disables the\nACL attached to the collection.\n"
                      },
                      "_owner": {
                        "description": "The owner of the collection. This is set to the user of the parent collection.\nMismatching owners will result in an API error. Only users are allowed, no groups.\n",
                        "type": "object",
                        "properties": {
                          "_basetype": {
                            "type": "string",
                            "enum": [
                              "user",
                              "group"
                            ]
                          },
                          "_owner": {
                            "type": "boolean",
                            "description": "Available only in some contexts, this flag indicated _the owner_ of an object.\n"
                          },
                          "_pool_contact": {
                            "type": "boolean",
                            "description": "Available only in some contexts, this flag indicates _the contact of a pool_ of an object.\n"
                          },
                          "user": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "number",
                                "format": "int64",
                                "description": "The id of the user.\n"
                              },
                              "_version": {
                                "type": "number",
                                "readOnly": true,
                                "format": "int64",
                                "description": "The version of the user record.\n"
                              },
                              "type": {
                                "type": "string",
                                "readOnly": true,
                                "enum": [
                                  "system",
                                  "easydb",
                                  "easydb_self_register",
                                  "anonymous",
                                  "collection",
                                  "email",
                                  "ldap",
                                  "sso"
                                ]
                              },
                              "_generated_displayname": {
                                "type": "string",
                                "readOnly": true,
                                "description": "System generated displayname. This is the user's `displayname`,\n`last_name` \u0026 `first_name`, `login` or `email`. If none of these is\nset, the `_id` is used.\n"
                              },
                              "login": {
                                "type": "string",
                                "readOnly": true,
                                "description": "Set for users of type `collection` or `email`.\n"
                              },
                              "frontend_language": {
                                "type": "string",
                                "readOnly": true,
                                "description": "The preferred frontend language of the user (BCP 47)\n"
                              }
                            }
                          },
                          "group": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "number",
                                "format": "int64",
                                "description": "The id of the group.\n"
                              },
                              "_generated_displayname": {
                                "type": "string",
                                "readOnly": true,
                                "description": "System generated displayname. This is the groups's `displayname`,\n`name` or `reference`. Rendered in the frontend language of the\ncurrent user. If none of these is set, the `_id` is used.\n"
                              }
                            }
                          }
                        }
                      },
                      "objects": {
                        "description": "Objects linked in this collection. This is only supported as writable property for PUT /collection.\n",
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "_global_object_id": {
                              "type": "string",
                              "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                            },
                            "webfrontend_props": {
                              "type": "object",
                              "additionalProperties": true,
                              "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                            },
                            "lookup:_global_object_id": {
                              "type": "object",
                              "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                              "properties": {
                                "_allow_defer": {
                                  "type": "boolean"
                                },
                                "_objecttype": {
                                  "type": "string"
                                },
                                "_system_object_id": {
                                  "type": "integer"
                                },
                                "_uuid": {
                                  "type": "string"
                                },
                                "additionalProperties": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      "_hotfolder_upload_urls": {
                        "description": "A list of URLs to upload files into this collection.\n",
                        "type": "array",
                        "readOnly": true,
                        "items": {
                          "type": "object",
                          "properties": {
                            "type": {
                              "description": "The type `webdav` indicates the enabled read \u0026 write WebDAV access. The type `webdav-hotfolder``\nis a writable WebDAV access which allows the user to drop files into the collection.\n",
                              "type": "string",
                              "enum": [
                                "webdav",
                                "webdav-hotfolder"
                              ]
                            },
                            "url": {
                              "type": "string",
                              "format": "url"
                            }
                          }
                        }
                      },
                      "_has_pin": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "This flag indicates that the collection has a pin code. The actual pin code is only visible\nto `system.root` users and users with the `BAG_ACL`.\n"
                      },
                      "pin_ok": {
                        "type": "boolean",
                        "readOnly": true,
                        "description": "Flag to indicate that the pin was entered correctly for the current user. `system.root` and\nall users with the `BAG_ACL` permission will always see `pin_ok`.\n"
                      },
                      "_created_at": {
                        "type": "string",
                        "format": "RFC3339_date",
                        "readOnly": true,
                        "description": "Timestamp when this collection was created.\n"
                      },
                      "_updated_at": {
                        "type": "string",
                        "format": "RFC3339_date",
                        "readOnly": true,
                        "description": "Timestamp when this collection was updated.\n"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required permission. See `code`\nfor the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The parent collection addressed by the URL does not exist.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/collection/objects/{collectionId}": {
      "x-path": "/collection/objects",
      "description": "Read or replace the objects linked to the collection identified by\n`collectionId`. `GET` returns the linked objects; `POST` replaces the\nentire list, linking exactly the objects in the body and unlinking any\nthat are absent. The collection `_version` is not changed.\n",
      "get": {
        "summary": "Retrieve objects of a collection.",
        "description": "* Requires an authenticated user with `BAG_READ` permission.\n* The linked objects of the addressed collection are returned in `position`\n  order, paginated by `offset` / `limit`.\n",
        "parameters": [
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "The offset when requesting the collection object list."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "The limit when requesting the collection object list. Default is _100_."
          },
          {
            "name": "collection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The collection id of the collection to access.\n"
          },
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "List of collection objects.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_version": {
                      "type": "integer",
                      "readOnly": true,
                      "description": "The `_version` of the collection.\n"
                    },
                    "count": {
                      "type": "integer",
                      "description": "The number of objects linked to this collection. In\n`/api/collection/splice` the number of objects to delete. Use `-1` to\ndelete all objects.\n"
                    },
                    "index": {
                      "type": "integer",
                      "nullable": true,
                      "description": "The index to use for `/api/collection/splice`. Index `0` is to the left of\nthe first object. Index which equals the number of existing objects in the\ncollection is to the right of the last object.\n"
                    },
                    "offset": {
                      "type": "integer",
                      "readOnly": true,
                      "description": "The offset of list of objects.\n"
                    },
                    "limit": {
                      "type": "integer",
                      "readOnly": true,
                      "description": "The maximum count of objects to list.\n"
                    },
                    "objects": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_global_object_id": {
                            "type": "string",
                            "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                          },
                          "webfrontend_props": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                          },
                          "lookup:_global_object_id": {
                            "type": "object",
                            "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                            "properties": {
                              "_allow_defer": {
                                "type": "boolean"
                              },
                              "_objecttype": {
                                "type": "string"
                              },
                              "_system_object_id": {
                                "type": "integer"
                              },
                              "_uuid": {
                                "type": "string"
                              },
                              "additionalProperties": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required permission (BAG_READ on\nthe collection for GET, plus LINK/UNLINK on the objects for\nPOST). See `code` for the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The collection addressed by the URL does not exist.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Replace objects of a collection.",
        "description": "* Replaces the entire object list: the collection is linked to exactly\n  the objects in the request body, and any object not present in the\n  body is unlinked.\n* Requires an authenticated user with `BAG_READ` permission.\n* Linking objects to a collection requires `LINK` permission.\n* If objects will be unlinked from the collection, the `UNLINK` permission is needed.\n* The `_version` of the collection is not changed.\n",
        "parameters": [
          {
            "name": "collection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The collection id of the collection to access.\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "Allow storing the collection even if the owner doesn't have the necessary\npermissions for all objects to share the rights defined in the `_acl` property\nof the collection. The `_invalid_acl` flag will be set, if the user doesn't\nhave sufficient permissions to share all objects of the collection. The user\nneeds the permission `BAG_ACL` for the collection in order to use this\nparameter.\n\nDiffers from easydb 5: this confirmation is driven by the boolean\n`allow_invalid_acl` parameter. easydb 5 instead resolves the `202`\nconfirmation with a `collection_rights_policy` query parameter; there is no\n`allow_invalid_acl` parameter in easydb 5.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, the invalid-ACL validity check (whether the collection owner may\ngrant the rights of all linked objects) is not run inline. Instead a queued\n`ACTION_COLLECTION_ACL_CHECK` job is scheduled and the request returns\nimmediately, before the check has resolved.\n"
          },
          {
            "name": "skip_index",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, do not queue index jobs for objects added to or removed from the\ncollection.\n"
          },
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "_version": {
                    "type": "integer",
                    "readOnly": true,
                    "description": "The `_version` of the collection.\n"
                  },
                  "count": {
                    "type": "integer",
                    "description": "The number of objects linked to this collection. In\n`/api/collection/splice` the number of objects to delete. Use `-1` to\ndelete all objects.\n"
                  },
                  "index": {
                    "type": "integer",
                    "nullable": true,
                    "description": "The index to use for `/api/collection/splice`. Index `0` is to the left of\nthe first object. Index which equals the number of existing objects in the\ncollection is to the right of the last object.\n"
                  },
                  "offset": {
                    "type": "integer",
                    "readOnly": true,
                    "description": "The offset of list of objects.\n"
                  },
                  "limit": {
                    "type": "integer",
                    "readOnly": true,
                    "description": "The maximum count of objects to list.\n"
                  },
                  "objects": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "_global_object_id": {
                          "type": "string",
                          "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "lookup:_global_object_id": {
                          "type": "object",
                          "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                          "properties": {
                            "_allow_defer": {
                              "type": "boolean"
                            },
                            "_objecttype": {
                              "type": "string"
                            },
                            "_system_object_id": {
                              "type": "integer"
                            },
                            "_uuid": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Short response of containing only the number of objects.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_version": {
                      "type": "integer",
                      "readOnly": true,
                      "description": "The `_version` of the collection.\n"
                    },
                    "count": {
                      "type": "integer",
                      "readOnly": true,
                      "description": "The number of objects linked to this collection.\n"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The collection owner lacks a grantable right for a linked object\nand the caller has `BAG_ACL`. Re-send with `allow_invalid_acl=true`\nto store the collection with sharing disabled.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionRemoveNotAllObjectsFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required permission (BAG_READ on\nthe collection for GET, plus LINK/UNLINK on the objects for\nPOST). See `code` for the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The collection addressed by the URL does not exist.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/collection/remove/{collectionId}": {
      "x-path": "/collection/remove",
      "description": "Unlink the listed objects from the collection identified by\n`collectionId`. The body is a bare JSON array of objects (each by\n`_global_object_id` or `lookup:_global_object_id`); if any object is not\ncurrently linked the call fails with `400 CollectionRemoveNotAllObjectsFound`.\nThe collection `_version` is not changed.\n",
      "post": {
        "summary": "Remove the listed objects from a collection.",
        "description": "* Requires an authenticated user with `BAG_READ` permission.\n* Unlinking objects from the collection requires the `UNLINK` permission.\n* The request body is a bare JSON array of objects to unlink (each\n  identified by `_global_object_id` or `lookup:_global_object_id`).\n  Unlike `push` / `splice`, the array is sent directly, not wrapped in\n  an `objects` property.\n* If one or more objects in the body are not currently linked to the\n  collection, the call fails with `400 CollectionRemoveNotAllObjectsFound`.\n* The `_version` of the collection is not changed.\n",
        "parameters": [
          {
            "name": "collection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The collection id of the collection to access.\n"
          },
          {
            "name": "skip_index",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, do not queue index jobs for objects added to or removed from the\ncollection.\n"
          },
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "description": "A bare JSON array of objects to unlink (each identified by\n`_global_object_id` or `lookup:_global_object_id`). Unlike\n`push` / `splice`, the array is sent directly, not wrapped in an\n`objects` property.\n",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "_global_object_id": {
                      "type": "string",
                      "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                    },
                    "webfrontend_props": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                    },
                    "lookup:_global_object_id": {
                      "type": "object",
                      "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                      "properties": {
                        "_allow_defer": {
                          "type": "boolean"
                        },
                        "_objecttype": {
                          "type": "string"
                        },
                        "_system_object_id": {
                          "type": "integer"
                        },
                        "_uuid": {
                          "type": "string"
                        },
                        "additionalProperties": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Short response of containing only the number of objects.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_version": {
                      "type": "integer",
                      "description": "The `_version` of the collection.\n"
                    },
                    "count": {
                      "type": "integer",
                      "description": "The number of objects linked to this collection.\n"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. In particular, the response\n`code` may be `CollectionRemoveNotAllObjectsFound` if one or\nmore objects in the payload are not in the collection.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionRemoveNotAllObjectsFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required permission (`BAG_READ`\non the collection, `UNLINK` on the objects).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The collection addressed by the URL does not exist.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/collection/push/{collectionId}": {
      "x-path": "/collection/push",
      "description": "Append objects to the end of the collection identified by `collectionId`,\nin request order. Objects already linked are moved to the end. The\ncollection `_version` is not changed.\n",
      "post": {
        "summary": "Append objects to a collection.",
        "description": "* Requires an authenticated user with `BAG_READ` permission.\n* Linking objects to a collection requires `LINK` permission.\n* If objects already exist in the collection, they will be moved to the end.\n* The objects are appended in order of the request.\n* The `_version` of the collection is not changed.\n",
        "parameters": [
          {
            "name": "collection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The collection id of the collection to access.\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "Allow storing the collection even if the owner doesn't have the necessary\npermissions for all objects to share the rights defined in the `_acl` property\nof the collection. The `_invalid_acl` flag will be set, if the user doesn't\nhave sufficient permissions to share all objects of the collection. The user\nneeds the permission `BAG_ACL` for the collection in order to use this\nparameter.\n\nDiffers from easydb 5: this confirmation is driven by the boolean\n`allow_invalid_acl` parameter. easydb 5 instead resolves the `202`\nconfirmation with a `collection_rights_policy` query parameter; there is no\n`allow_invalid_acl` parameter in easydb 5.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, the invalid-ACL validity check (whether the collection owner may\ngrant the rights of all linked objects) is not run inline. Instead a queued\n`ACTION_COLLECTION_ACL_CHECK` job is scheduled and the request returns\nimmediately, before the check has resolved.\n"
          },
          {
            "name": "skip_index",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, do not queue index jobs for objects added to or removed from the\ncollection.\n"
          },
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "_version": {
                    "type": "integer",
                    "readOnly": true,
                    "description": "The `_version` of the collection.\n"
                  },
                  "count": {
                    "type": "integer",
                    "description": "The number of objects linked to this collection. In\n`/api/collection/splice` the number of objects to delete. Use `-1` to\ndelete all objects.\n"
                  },
                  "index": {
                    "type": "integer",
                    "nullable": true,
                    "description": "The index to use for `/api/collection/splice`. Index `0` is to the left of\nthe first object. Index which equals the number of existing objects in the\ncollection is to the right of the last object.\n"
                  },
                  "offset": {
                    "type": "integer",
                    "readOnly": true,
                    "description": "The offset of list of objects.\n"
                  },
                  "limit": {
                    "type": "integer",
                    "readOnly": true,
                    "description": "The maximum count of objects to list.\n"
                  },
                  "objects": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "_global_object_id": {
                          "type": "string",
                          "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "lookup:_global_object_id": {
                          "type": "object",
                          "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                          "properties": {
                            "_allow_defer": {
                              "type": "boolean"
                            },
                            "_objecttype": {
                              "type": "string"
                            },
                            "_system_object_id": {
                              "type": "integer"
                            },
                            "_uuid": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Short response of containing only the number of objects.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_version": {
                      "type": "integer",
                      "description": "The `_version` of the collection.\n"
                    },
                    "count": {
                      "type": "integer",
                      "description": "The number of objects linked to this collection.\n"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The collection owner lacks a grantable right for a linked object\nand the caller has `BAG_ACL`. Re-send with `allow_invalid_acl=true`\nto store the collection with sharing disabled.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionRemoveNotAllObjectsFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required permission (`BAG_READ`\non the collection, `LINK` on the objects to be appended).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The collection addressed by the URL does not exist.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/collection/splice/{collectionId}": {
      "x-path": "/collection/splice",
      "description": "Splice the object list of the collection identified by `collectionId`:\nremove `count` objects at position `index` and insert the supplied\n`objects` at that position. The request body is a single object carrying\nthe `index`, `count` and `objects` fields. The collection `_version` is\nnot changed.\n",
      "post": {
        "summary": "Remove and add objects to a collection.",
        "description": "* The splice call removes `count` objects at position `index` and adds the\n  delivered `objects` at that position. Existing objects are moved to make room.\n* `index`, `count` and `objects` are supplied as fields of the request body\n  object, not as query parameters.\n* `index` must be `\u003e= 0` and must not exceed the current number of objects.\n  `count` must be `\u003e= -1`; `-1` deletes all objects from `index` to the end.\n* Requires an authenticated user with `BAG_READ` permission.\n* Linking objects to a collection requires `LINK` permission.\n* If objects will be unlinked from the collection, the `UNLINK` permission is needed.\n* The `_version` of the collection is not changed.\n",
        "parameters": [
          {
            "name": "collection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The collection id of the collection to access.\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "Allow storing the collection even if the owner doesn't have the necessary\npermissions for all objects to share the rights defined in the `_acl` property\nof the collection. The `_invalid_acl` flag will be set, if the user doesn't\nhave sufficient permissions to share all objects of the collection. The user\nneeds the permission `BAG_ACL` for the collection in order to use this\nparameter.\n\nDiffers from easydb 5: this confirmation is driven by the boolean\n`allow_invalid_acl` parameter. easydb 5 instead resolves the `202`\nconfirmation with a `collection_rights_policy` query parameter; there is no\n`allow_invalid_acl` parameter in easydb 5.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, the invalid-ACL validity check (whether the collection owner may\ngrant the rights of all linked objects) is not run inline. Instead a queued\n`ACTION_COLLECTION_ACL_CHECK` job is scheduled and the request returns\nimmediately, before the check has resolved.\n"
          },
          {
            "name": "skip_index",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "boolean"
            },
            "description": "If set, do not queue index jobs for objects added to or removed from the\ncollection.\n"
          },
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "_version": {
                    "type": "integer",
                    "readOnly": true,
                    "description": "The `_version` of the collection.\n"
                  },
                  "count": {
                    "type": "integer",
                    "description": "The number of objects linked to this collection. In\n`/api/collection/splice` the number of objects to delete. Use `-1` to\ndelete all objects.\n"
                  },
                  "index": {
                    "type": "integer",
                    "nullable": true,
                    "description": "The index to use for `/api/collection/splice`. Index `0` is to the left of\nthe first object. Index which equals the number of existing objects in the\ncollection is to the right of the last object.\n"
                  },
                  "offset": {
                    "type": "integer",
                    "readOnly": true,
                    "description": "The offset of list of objects.\n"
                  },
                  "limit": {
                    "type": "integer",
                    "readOnly": true,
                    "description": "The maximum count of objects to list.\n"
                  },
                  "objects": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "_global_object_id": {
                          "type": "string",
                          "description": "The object id identifying the object. This is considered a local object if has\nthe format `\u003csystem object id\u003e@local` or `\u003csystem object id\u003e@\u003cdb uuid\u003e`. All other ids\nare considered foreign and accepted without further checks. Local ids are checked\nfor existance.\n"
                        },
                        "webfrontend_props": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "An object to store custom data for collections. Frontends are advised\nto use their own top level property here and put all custom data\nunderneath. Other top level data should be stored back as is. The\nserver applies no processing to that data.\n"
                        },
                        "lookup:_global_object_id": {
                          "type": "object",
                          "description": "Object lookups can use `_system_object_id` or `_uuid` to find existing objects. If objects are promised to\nbe injected into **fylr**, `_allow_defer` can be set. Custom columns can also be used to find an object.\n",
                          "properties": {
                            "_allow_defer": {
                              "type": "boolean"
                            },
                            "_objecttype": {
                              "type": "string"
                            },
                            "_system_object_id": {
                              "type": "integer"
                            },
                            "_uuid": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Short response of containing only the number of objects.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_version": {
                      "type": "integer",
                      "description": "The `_version` of the collection.\n"
                    },
                    "count": {
                      "type": "integer",
                      "description": "The number of objects linked to this collection.\n"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The collection owner lacks a grantable right for a linked object\nand the caller has `BAG_ACL`. Re-send with `allow_invalid_acl=true`\nto store the collection with sharing disabled.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Collection202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionRemoveNotAllObjectsFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required permission (`BAG_READ`\non the collection, `LINK` on inserted objects, `UNLINK` on\nremoved objects).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/CollectionObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The collection addressed by the URL does not exist.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/config/list": {
      "description": "Read the list of available base-config variable definitions. The list is\ncompiled dynamically from fylr's fixed core config items plus any items\ncontributed by loaded plugins, so it varies with the installed plugin set.\nIt describes the config schema (the items a frontend renders into a config\nform); the stored values are read and written through `/config`. Requires\nthe `system.config` system right (`system.root` always satisfies it).\n",
      "get": {
        "summary": "Get config list",
        "tags": [
          "config"
        ],
        "description": "The list is a dynamic compilation of available config varibles. It includes\nfixed config variables of FYLR's base config as well as variables provided\nby plugins.\n",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "system": {
                      "type": "object",
                      "properties": {
                        "defs": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "description": "Each item describes a config setting.",
                            "properties": {
                              "name": {
                                "type": "string",
                                "description": "The unique name of this config"
                              },
                              "group": {
                                "type": "string",
                                "description": "The **group** sets the tab this config variable is in."
                              },
                              "parameters": {
                                "$ref": "#/components/schemas/ConfigParam"
                              },
                              "require_system_right": {
                                "type": "string",
                                "description": "System right which this config requires, e.g. \"system.root\" if it requires root rights."
                              },
                              "unauthenticated_visible": {
                                "type": "boolean",
                                "description": "If true, this config is visible to unauthenticated sessions (access token with no user)."
                              },
                              "unavailable": {
                                "type": "boolean",
                                "description": "If true, the feature this section configures is not available on\nthis instance (e.g. not included in the license). Frontends should\nrender the section greyed out but visible. Computed per request;\nomitted when false.\n"
                              }
                            }
                          }
                        }
                      }
                    },
                    "plugin": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "description": "_key_ is the name of the plugin",
                        "properties": {
                          "defs": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "description": "Each item describes a config setting.",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "description": "The unique name of this config"
                                },
                                "group": {
                                  "type": "string",
                                  "description": "The **group** sets the tab this config variable is in."
                                },
                                "parameters": {
                                  "$ref": "#/components/schemas/ConfigParam"
                                },
                                "require_system_right": {
                                  "type": "string",
                                  "description": "System right which this config requires, e.g. \"system.root\" if it requires root rights."
                                },
                                "unauthenticated_visible": {
                                  "type": "boolean",
                                  "description": "If true, this config is visible to unauthenticated sessions (access token with no user)."
                                },
                                "unavailable": {
                                  "type": "boolean",
                                  "description": "If true, the feature this section configures is not available on\nthis instance (e.g. not included in the license). Frontends should\nrender the section greyed out but visible. Computed per request;\nomitted when false.\n"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.config` system right\n(`system.root` always satisfies it). `code` is `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/config": {
      "description": "Administrators can define base configuration using this API. fylr has a basic\nset of configuration items which are in the core system, such as the name of\nthe instance, administrator's main address, language definitions and so on.\n\nFrontends are required to implement a generic form editor for base\nconfiguration items. The list of items can be retrieved using the\n[config/list](list/) API.\n\nThis list is not stable and can be changed without API change in any new\nversion of fylr. Plugins can extend the list of configuration items. So,\ndepending on the list of loaded plugins in fylr, the list has a various number\nof items.\n",
      "get": {
        "summary": "Get all base configuration",
        "tags": [
          "config"
        ],
        "description": "Any authenticated user may read the config; items the session is not\npermitted to read are filtered out of the response rather than causing a\n`403`. The request itself is never rejected for lack of `system.config`.\n\nDiffers from easydb 5: reading the config does not require the\n`system.config` system right (in easydb 5 the `GET` config call requires\n`system.config`); fylr instead filters out the items the session may not\nread.\n",
        "responses": {
          "200": {
            "description": "The response contains the base configuration values. Items the session\nis not permitted to read are omitted.\n",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "plugin": {
                      "properties": {
                        "formula-columns": {
                          "properties": {
                            "config": {
                              "properties": {
                                "api_user": {
                                  "$ref": "#/components/schemas/user_config",
                                  "type": "object",
                                  "x-type": "user"
                                }
                              },
                              "type": "object"
                            }
                          },
                          "type": "object"
                        }
                      },
                      "type": "object"
                    },
                    "system": {
                      "properties": {
                        "config": {
                          "properties": {
                            "appearance": {
                              "properties": {
                                "background_color": {
                                  "type": "string"
                                },
                                "brand_color": {
                                  "type": "string"
                                },
                                "favicon": {
                                  "properties": {
                                    "_id": {
                                      "description": "The EAS-ID of the file.",
                                      "type": "integer"
                                    },
                                    "frontend_prefs": {
                                      "additionalProperties": {
                                        "description": "Any value is allowed"
                                      },
                                      "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                      "type": "object"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "file"
                                },
                                "login_background": {
                                  "properties": {
                                    "_id": {
                                      "description": "The EAS-ID of the file.",
                                      "type": "integer"
                                    },
                                    "frontend_prefs": {
                                      "additionalProperties": {
                                        "description": "Any value is allowed"
                                      },
                                      "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                      "type": "object"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "file"
                                },
                                "logo": {
                                  "properties": {
                                    "_id": {
                                      "description": "The EAS-ID of the file.",
                                      "type": "integer"
                                    },
                                    "frontend_prefs": {
                                      "additionalProperties": {
                                        "description": "Any value is allowed"
                                      },
                                      "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                      "type": "object"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "file"
                                },
                                "logo_external_url": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "tag_colors": {
                                  "items": {
                                    "properties": {
                                      "tag_color": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "tag_icons": {
                                  "items": {
                                    "properties": {
                                      "fa-icon": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "welcome_splash": {
                                  "enum": [
                                    "custom_logo",
                                    "fylr",
                                    "off"
                                  ],
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "colorprofiles": {
                              "properties": {
                                "profiles": {
                                  "items": {
                                    "properties": {
                                      "profile": {
                                        "properties": {
                                          "_id": {
                                            "description": "The EAS-ID of the file.",
                                            "type": "integer"
                                          },
                                          "frontend_prefs": {
                                            "additionalProperties": {
                                              "description": "Any value is allowed"
                                            },
                                            "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                            "type": "object"
                                          }
                                        },
                                        "type": "object",
                                        "x-type": "file"
                                      },
                                      "profilename": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "custom_data_type_updater": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "custom_version_presets": {
                              "properties": {
                                "value": {
                                  "properties": {
                                    "presets": {
                                      "description": "Named presets of on-demand custom-version options. Each preset is offered in the download dialog and can be requested on export by name (an export version with `type` `custom` and `custom_version_preset` set to the preset's `name`).",
                                      "items": {
                                        "properties": {
                                          "custom": {
                                            "$ref": "#/components/schemas/ExportCustomVersion"
                                          },
                                          "displayname": {
                                            "type": "object",
                                            "properties": {
                                              "de-DE": {
                                                "type": "string"
                                              },
                                              "en-US": {
                                                "type": "string"
                                              }
                                            },
                                            "example": {
                                              "de-DE": "Deutscher text",
                                              "en-US": "English text"
                                            }
                                          },
                                          "name": {
                                            "description": "Unique name of the preset. Referenced on export via `custom_version_preset` and used in place of `custom` in the produced file name.",
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "type": "array"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "json"
                                }
                              },
                              "type": "object"
                            },
                            "deep_link_access": {
                              "properties": {
                                "allow_access_by_column": {
                                  "type": "boolean"
                                },
                                "allow_access_by_id": {
                                  "type": "boolean"
                                },
                                "enabled": {
                                  "type": "boolean"
                                },
                                "iiif_default_links": {
                                  "type": "boolean"
                                },
                                "iiif_links": {
                                  "items": {
                                    "properties": {
                                      "html_code": {
                                        "type": "string"
                                      },
                                      "label": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "iiif_required_statement": {
                                  "properties": {
                                    "label": {
                                      "properties": {
                                        "de-DE": {
                                          "type": "string"
                                        },
                                        "en-US": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "value": {
                                      "properties": {
                                        "de-DE": {
                                          "type": "string"
                                        },
                                        "en-US": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    }
                                  },
                                  "type": "object"
                                },
                                "include_parents": {
                                  "type": "boolean"
                                },
                                "merge_linked_objects": {
                                  "enum": [
                                    "all",
                                    "in_main_search",
                                    "none",
                                    "not_in_main_search",
                                    "not_in_main_search_unless_reverse"
                                  ],
                                  "type": "string"
                                },
                                "merge_max_depth": {
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "detail_deep_link": {
                              "properties": {
                                "use_system_object_id": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "email": {
                              "properties": {
                                "admin_emails": {
                                  "items": {
                                    "properties": {
                                      "email": {
                                        "format": "email",
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "from": {
                                  "format": "email",
                                  "type": "string"
                                },
                                "signature": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "email_server": {
                              "properties": {
                                "cram_md5_auth": {
                                  "properties": {
                                    "password": {
                                      "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                      "type": "string"
                                    },
                                    "username": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "helo_domain": {
                                  "type": "string"
                                },
                                "insecure_skip_verify": {
                                  "type": "boolean"
                                },
                                "login_auth": {
                                  "properties": {
                                    "password": {
                                      "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                      "type": "string"
                                    },
                                    "username": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "plain_auth": {
                                  "properties": {
                                    "identity": {
                                      "type": "string"
                                    },
                                    "password": {
                                      "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                      "type": "string"
                                    },
                                    "username": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "server_addr": {
                                  "type": "string"
                                },
                                "type": {
                                  "enum": [
                                    "off",
                                    "starttls",
                                    "tls"
                                  ],
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "export": {
                              "properties": {
                                "xslts": {
                                  "items": {
                                    "properties": {
                                      "content_type": {
                                        "type": "string"
                                      },
                                      "description": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "displayname": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "namespace": {
                                        "type": "string"
                                      },
                                      "oai_pmh_prefix": {
                                        "type": "string"
                                      },
                                      "schema": {
                                        "type": "string"
                                      },
                                      "use_for_api_objects": {
                                        "type": "boolean"
                                      },
                                      "use_for_oai_pmh": {
                                        "type": "boolean"
                                      },
                                      "xpath_query": {
                                        "type": "string"
                                      },
                                      "xslt": {
                                        "properties": {
                                          "_id": {
                                            "description": "The EAS-ID of the file.",
                                            "type": "integer"
                                          },
                                          "frontend_prefs": {
                                            "additionalProperties": {
                                              "description": "Any value is allowed"
                                            },
                                            "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                            "type": "object"
                                          }
                                        },
                                        "type": "object",
                                        "x-type": "file"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "export_scheduler": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "file_url_expire": {
                              "properties": {
                                "deep_link_days": {
                                  "type": "integer"
                                },
                                "default_days": {
                                  "type": "integer"
                                },
                                "max_days": {
                                  "type": "integer"
                                },
                                "oai_pmh_days": {
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "indexer": {
                              "properties": {
                                "default_analyzer": {
                                  "properties": {
                                    "icu_folding": {
                                      "type": "boolean"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "janitor": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                },
                                "event_remote_addr_expire_days": {
                                  "type": "integer"
                                },
                                "events": {
                                  "properties": {
                                    "expire_days_ADMIN": {
                                      "type": "integer"
                                    },
                                    "expire_days_DOWNLOAD": {
                                      "type": "integer"
                                    },
                                    "expire_days_EXPORT": {
                                      "type": "integer"
                                    },
                                    "expire_days_FRONTEND": {
                                      "type": "integer"
                                    },
                                    "expire_days_INDEX": {
                                      "type": "integer"
                                    },
                                    "expire_days_LOGIN_LOGOUT": {
                                      "type": "integer"
                                    },
                                    "expire_days_PLUGIN": {
                                      "type": "integer"
                                    },
                                    "expire_days_SYSTEM": {
                                      "type": "integer"
                                    },
                                    "expire_days_TASK": {
                                      "type": "integer"
                                    },
                                    "expire_days_UPLOAD": {
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "file_expire_days": {
                                  "type": "integer"
                                },
                                "object_and_file_removal": {
                                  "properties": {
                                    "allow_overwrite": {
                                      "type": "boolean"
                                    },
                                    "file_link_delete": {
                                      "properties": {
                                        "keep_count_history_versions": {
                                          "type": "integer"
                                        },
                                        "keep_days_history_versions": {
                                          "type": "integer"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "object_purge": {
                                      "properties": {
                                        "min_deleted_days": {
                                          "type": "integer"
                                        }
                                      },
                                      "type": "object"
                                    }
                                  },
                                  "type": "object"
                                },
                                "users": {
                                  "properties": {
                                    "archive_nonactive_after_days": {
                                      "type": "integer"
                                    },
                                    "archive_types": {
                                      "items": {
                                        "enum": [
                                          "anonymous",
                                          "easydb",
                                          "easydb_self_register",
                                          "ldap",
                                          "sso"
                                        ],
                                        "type": "string"
                                      },
                                      "type": "array"
                                    },
                                    "delete_archived_after_days": {
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "languages": {
                              "properties": {
                                "database": {
                                  "items": {
                                    "properties": {
                                      "analyzer": {
                                        "properties": {
                                          "icu_folding": {
                                            "type": "boolean"
                                          },
                                          "synonyms": {
                                            "type": "string"
                                          },
                                          "synonyms_file": {
                                            "properties": {
                                              "_id": {
                                                "description": "The EAS-ID of the file.",
                                                "type": "integer"
                                              },
                                              "frontend_prefs": {
                                                "additionalProperties": {
                                                  "description": "Any value is allowed"
                                                },
                                                "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                                "type": "object"
                                              }
                                            },
                                            "type": "object",
                                            "x-type": "file"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "date_format": {
                                        "enum": [
                                          "ca",
                                          "cldr",
                                          "da",
                                          "de",
                                          "us"
                                        ],
                                        "type": "string"
                                      },
                                      "displayname": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "number_format": {
                                        "enum": [
                                          "ca",
                                          "cldr",
                                          "de",
                                          "fi",
                                          "it",
                                          "us"
                                        ],
                                        "type": "string"
                                      },
                                      "time_format": {
                                        "enum": [
                                          "cldr",
                                          "da",
                                          "de",
                                          "us"
                                        ],
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "frontend": {
                                  "items": {
                                    "enum": [
                                      "da-DK",
                                      "de-DE",
                                      "en-US",
                                      "fi-FI",
                                      "fr-FR",
                                      "it-IT",
                                      "ru-RU",
                                      "sv-SE",
                                      "tvl-TV",
                                      "uz-UZ"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "ldap": {
                              "properties": {
                                "bindpassword": {
                                  "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                  "type": "string"
                                },
                                "bindusername": {
                                  "type": "string"
                                },
                                "connections": {
                                  "items": {
                                    "properties": {
                                      "tls_ca_cert": {
                                        "type": "string"
                                      },
                                      "tls_insecure": {
                                        "type": "boolean"
                                      },
                                      "tls_start": {
                                        "type": "boolean"
                                      },
                                      "url": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "debug": {
                                  "type": "boolean"
                                },
                                "groupbasedn": {
                                  "type": "string"
                                },
                                "groupfilter": {
                                  "type": "string"
                                },
                                "groupmapping": {
                                  "items": {
                                    "properties": {
                                      "group": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "userbasedn": {
                                  "type": "string"
                                },
                                "userfilter": {
                                  "type": "string"
                                },
                                "usermapping": {
                                  "items": {
                                    "properties": {
                                      "key": {
                                        "enum": [
                                          "address_supplement",
                                          "company",
                                          "country",
                                          "department",
                                          "displayname",
                                          "email",
                                          "first_name",
                                          "house_number",
                                          "last_name",
                                          "login",
                                          "phone",
                                          "postal_code",
                                          "reference",
                                          "state",
                                          "street",
                                          "town"
                                        ],
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "userupdatecolumn": {
                                  "enum": [
                                    "email",
                                    "login",
                                    "reference"
                                  ],
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "license": {
                              "properties": {
                                "license": {
                                  "$ref": "#/components/schemas/License",
                                  "type": "object",
                                  "x-type": "license"
                                }
                              },
                              "type": "object"
                            },
                            "loca": {
                              "properties": {
                                "google_csv": {
                                  "items": {
                                    "properties": {
                                      "gid": {
                                        "type": "integer"
                                      },
                                      "key": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "google_overload_csv": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "location_defaults": {
                              "properties": {
                                "backups": {
                                  "description": "Name of storage location as defined in the location manager",
                                  "enum": [
                                    "file"
                                  ],
                                  "nullable": true,
                                  "type": "string"
                                },
                                "originals": {
                                  "description": "Name of storage location as defined in the location manager",
                                  "enum": [
                                    "file"
                                  ],
                                  "nullable": true,
                                  "type": "string"
                                },
                                "versions": {
                                  "description": "Name of storage location as defined in the location manager",
                                  "enum": [
                                    "file"
                                  ],
                                  "nullable": true,
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "logging": {
                              "properties": {
                                "level": {
                                  "enum": [
                                    "",
                                    "debug",
                                    "error",
                                    "info",
                                    "trace",
                                    "warn"
                                  ],
                                  "type": "string"
                                },
                                "timings": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "login": {
                              "properties": {
                                "guest": {
                                  "type": "boolean"
                                },
                                "info": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "keep_login": {
                                  "enum": [
                                    "30d",
                                    "7d",
                                    "off"
                                  ],
                                  "type": "string"
                                },
                                "label": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "placeholder": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "name": {
                              "properties": {
                                "description": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "internal_name": {
                                  "type": "string"
                                },
                                "title": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "notification_scheduler": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "oai_pmh": {
                              "properties": {
                                "admin_email": {
                                  "items": {
                                    "properties": {
                                      "email": {
                                        "format": "email",
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "enabled": {
                                  "type": "boolean"
                                },
                                "include_parents": {
                                  "type": "boolean"
                                },
                                "merge_linked_objects": {
                                  "enum": [
                                    "all",
                                    "in_main_search",
                                    "none",
                                    "not_in_main_search",
                                    "not_in_main_search_unless_reverse"
                                  ],
                                  "type": "string"
                                },
                                "merge_max_depth": {
                                  "type": "integer"
                                },
                                "namespace_identifier": {
                                  "type": "string"
                                },
                                "records_limit": {
                                  "type": "integer"
                                },
                                "repository_name": {
                                  "type": "string"
                                },
                                "tagfilter_deleted": {
                                  "description": "Tag filter definition with any, all and not",
                                  "properties": {
                                    "all": {
                                      "items": {
                                        "description": "List of tag ids which are all required",
                                        "type": "integer"
                                      },
                                      "type": "array"
                                    },
                                    "any": {
                                      "items": {
                                        "description": "List of tag ids of which at least one is required to match",
                                        "type": "integer"
                                      },
                                      "type": "array"
                                    },
                                    "not": {
                                      "items": {
                                        "description": "List of tag ids which must not match",
                                        "type": "integer"
                                      },
                                      "type": "array"
                                    }
                                  },
                                  "type": "object"
                                },
                                "tagfilter_sets": {
                                  "items": {
                                    "properties": {
                                      "set_name": {
                                        "type": "string"
                                      },
                                      "tagfilter": {
                                        "description": "Tag filter definition with any, all and not",
                                        "properties": {
                                          "all": {
                                            "items": {
                                              "description": "List of tag ids which are all required",
                                              "type": "integer"
                                            },
                                            "type": "array"
                                          },
                                          "any": {
                                            "items": {
                                              "description": "List of tag ids of which at least one is required to match",
                                              "type": "integer"
                                            },
                                            "type": "array"
                                          },
                                          "not": {
                                            "items": {
                                              "description": "List of tag ids which must not match",
                                              "type": "integer"
                                            },
                                            "type": "array"
                                          }
                                        },
                                        "type": "object"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "oauth2": {
                              "properties": {
                                "clients": {
                                  "items": {
                                    "properties": {
                                      "name": {
                                        "type": "string"
                                      },
                                      "redirect_uris": {
                                        "items": {
                                          "properties": {
                                            "url": {
                                              "type": "string"
                                            }
                                          },
                                          "type": "object"
                                        },
                                        "type": "array"
                                      },
                                      "secret": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "expirations": {
                                  "properties": {
                                    "access_token": {
                                      "type": "string"
                                    },
                                    "refresh_token": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "objectstore": {
                              "properties": {
                                "instance": {
                                  "type": "string"
                                },
                                "server": {
                                  "type": "string"
                                },
                                "uid": {
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "openapi_spec_endpoint": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "openid": {
                              "properties": {
                                "userinfo": {
                                  "items": {
                                    "enum": [
                                      "address_supplement",
                                      "company",
                                      "country",
                                      "department",
                                      "displayname",
                                      "email",
                                      "first_name",
                                      "house_number",
                                      "last_name",
                                      "phone",
                                      "postal_code",
                                      "state",
                                      "street",
                                      "town"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "password": {
                              "properties": {
                                "blockclient": {
                                  "properties": {
                                    "attempts": {
                                      "type": "integer"
                                    },
                                    "minutes": {
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "check": {
                                  "items": {
                                    "properties": {
                                      "regexp": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "hint": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "showforgot": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "produce_config": {
                              "properties": {
                                "value": {
                                  "properties": {
                                    "classes": {
                                      "description": "The produce config defines the renditions (preview versions) produce by the file workers. It includes the parameters for the recipes and defines file extension based routing.",
                                      "properties": {
                                        "audio": {
                                          "properties": {
                                            "name": {
                                              "description": "Read-only value with the name of the class.",
                                              "type": "string"
                                            },
                                            "rightsmanagement": {
                                              "description": "If set, this version will be configurable in the rights management of fylr.",
                                              "type": "boolean"
                                            },
                                            "sourceversion": {
                                              "description": "The version which is used to produce this version.",
                                              "type": "string"
                                            },
                                            "standard": {
                                              "description": "If set, this version will be included in the standard info.",
                                              "type": "boolean"
                                            },
                                            "uploadenabledextensions": {
                                              "items": {
                                                "description": "Extensions which are allowed in this class for upload.",
                                                "enum": [
                                                  "aac",
                                                  "aiff",
                                                  "dts",
                                                  "flac",
                                                  "m4a",
                                                  "mp2",
                                                  "mp3",
                                                  "oga",
                                                  "ogg",
                                                  "opus",
                                                  "ra",
                                                  "wav",
                                                  "wma"
                                                ],
                                                "type": "string"
                                              },
                                              "type": "array"
                                            },
                                            "uploadmaxfilesize": {
                                              "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                              "type": "string"
                                            },
                                            "versions": {
                                              "items": {
                                                "oneOf": [
                                                  {
                                                    "description": "Recipe \"audioconverter:convert\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "aac",
                                                                "aiff",
                                                                "dts",
                                                                "flac",
                                                                "m4a",
                                                                "mp2",
                                                                "mp3",
                                                                "oga",
                                                                "ogg",
                                                                "opus",
                                                                "ra",
                                                                "wav",
                                                                "wma"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "aac",
                                                            "aiff",
                                                            "dts",
                                                            "flac",
                                                            "m4a",
                                                            "mp2",
                                                            "mp3",
                                                            "oga",
                                                            "ogg",
                                                            "opus",
                                                            "ra",
                                                            "wav",
                                                            "wma"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format [select]",
                                                            "enum": [
                                                              "aac"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"audioconverter:convert\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"audioconverter:preview\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "aac",
                                                                "aiff",
                                                                "dts",
                                                                "flac",
                                                                "m4a",
                                                                "mp2",
                                                                "mp3",
                                                                "oga",
                                                                "ogg",
                                                                "opus",
                                                                "ra",
                                                                "wav",
                                                                "wma"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "aac",
                                                            "aiff",
                                                            "dts",
                                                            "flac",
                                                            "m4a",
                                                            "mp2",
                                                            "mp3",
                                                            "oga",
                                                            "ogg",
                                                            "opus",
                                                            "ra",
                                                            "wav",
                                                            "wma"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format of the thumbnail [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "resize_mode": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "height",
                                                              "max",
                                                              "min",
                                                              "width"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the output size. [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"audioconverter:preview\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"audioconverter:snippet\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "aac",
                                                                "aiff",
                                                                "dts",
                                                                "flac",
                                                                "m4a",
                                                                "mp2",
                                                                "mp3",
                                                                "oga",
                                                                "ogg",
                                                                "opus",
                                                                "ra",
                                                                "wav",
                                                                "wma"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "aac",
                                                            "aiff",
                                                            "dts",
                                                            "flac",
                                                            "m4a",
                                                            "mp2",
                                                            "mp3",
                                                            "oga",
                                                            "ogg",
                                                            "opus",
                                                            "ra",
                                                            "wav",
                                                            "wma"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "end": {
                                                            "description": "timestamp to end snippet [string]",
                                                            "type": "string"
                                                          },
                                                          "format": {
                                                            "description": " [string]",
                                                            "type": "string"
                                                          },
                                                          "start": {
                                                            "description": "timestamp to start snippet [string]",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"audioconverter:snippet\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  }
                                                ]
                                              },
                                              "type": "array"
                                            },
                                            "watermark": {
                                              "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                              "type": "boolean"
                                            }
                                          },
                                          "type": "object"
                                        },
                                        "image": {
                                          "properties": {
                                            "name": {
                                              "description": "Read-only value with the name of the class.",
                                              "type": "string"
                                            },
                                            "rightsmanagement": {
                                              "description": "If set, this version will be configurable in the rights management of fylr.",
                                              "type": "boolean"
                                            },
                                            "sourceversion": {
                                              "description": "The version which is used to produce this version.",
                                              "type": "string"
                                            },
                                            "standard": {
                                              "description": "If set, this version will be included in the standard info.",
                                              "type": "boolean"
                                            },
                                            "uploadenabledextensions": {
                                              "items": {
                                                "description": "Extensions which are allowed in this class for upload.",
                                                "enum": [
                                                  "ai",
                                                  "arw",
                                                  "avif",
                                                  "bmp",
                                                  "cr2",
                                                  "cr3",
                                                  "crw",
                                                  "dng",
                                                  "eps",
                                                  "gif",
                                                  "heic",
                                                  "ico",
                                                  "jfif",
                                                  "jp2",
                                                  "jpeg",
                                                  "jpg",
                                                  "nef",
                                                  "pcd",
                                                  "png",
                                                  "ppm",
                                                  "psd",
                                                  "raf",
                                                  "rw2",
                                                  "svg",
                                                  "tif",
                                                  "tiff",
                                                  "webp",
                                                  "wmf"
                                                ],
                                                "type": "string"
                                              },
                                              "type": "array"
                                            },
                                            "uploadmaxfilesize": {
                                              "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                              "type": "string"
                                            },
                                            "versions": {
                                              "items": {
                                                "oneOf": [
                                                  {
                                                    "description": "Recipe \"imageconverter:preview_pool_watermark\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "ai",
                                                                "arw",
                                                                "bmp",
                                                                "cr2",
                                                                "cr3",
                                                                "crw",
                                                                "dng",
                                                                "eps",
                                                                "gif",
                                                                "heic",
                                                                "ico",
                                                                "jfif",
                                                                "jp2",
                                                                "jpeg",
                                                                "jpg",
                                                                "nef",
                                                                "pcd",
                                                                "png",
                                                                "ppm",
                                                                "psd",
                                                                "raf",
                                                                "rw2",
                                                                "svg",
                                                                "tif",
                                                                "tiff",
                                                                "webp",
                                                                "wmf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "ai",
                                                            "arw",
                                                            "bmp",
                                                            "cr2",
                                                            "cr3",
                                                            "crw",
                                                            "dng",
                                                            "eps",
                                                            "gif",
                                                            "heic",
                                                            "ico",
                                                            "jfif",
                                                            "jp2",
                                                            "jpeg",
                                                            "jpg",
                                                            "nef",
                                                            "pcd",
                                                            "png",
                                                            "ppm",
                                                            "psd",
                                                            "raf",
                                                            "rw2",
                                                            "svg",
                                                            "tif",
                                                            "tiff",
                                                            "webp",
                                                            "wmf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format of the thumbnail [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png",
                                                              "webp"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "resize_mode": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "height",
                                                              "max",
                                                              "min",
                                                              "width"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the output size. [int]",
                                                            "type": "integer"
                                                          },
                                                          "size_minimum": {
                                                            "description": "Only produce version if source size (largest dimension, either `width` or `height`) is greater or equal `size_minimum`. [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"imageconverter:preview_pool_watermark\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"imageconverter:vectortosvg\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "ai",
                                                                "eps",
                                                                "wmf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "ai",
                                                            "eps",
                                                            "wmf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {},
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"imageconverter:vectortosvg\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"imageconverter:browserthumbs\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "ai",
                                                                "arw",
                                                                "avif",
                                                                "bmp",
                                                                "cr2",
                                                                "cr3",
                                                                "crw",
                                                                "dng",
                                                                "eps",
                                                                "gif",
                                                                "heic",
                                                                "ico",
                                                                "jfif",
                                                                "jp2",
                                                                "jpeg",
                                                                "jpg",
                                                                "nef",
                                                                "pcd",
                                                                "png",
                                                                "ppm",
                                                                "psd",
                                                                "raf",
                                                                "rw2",
                                                                "svg",
                                                                "tif",
                                                                "tiff",
                                                                "webp",
                                                                "wmf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "ai",
                                                            "arw",
                                                            "avif",
                                                            "bmp",
                                                            "cr2",
                                                            "cr3",
                                                            "crw",
                                                            "dng",
                                                            "eps",
                                                            "gif",
                                                            "heic",
                                                            "ico",
                                                            "jfif",
                                                            "jp2",
                                                            "jpeg",
                                                            "jpg",
                                                            "nef",
                                                            "pcd",
                                                            "png",
                                                            "ppm",
                                                            "psd",
                                                            "raf",
                                                            "rw2",
                                                            "svg",
                                                            "tif",
                                                            "tiff",
                                                            "webp",
                                                            "wmf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "background": {
                                                            "description": "For background color, defaults to black (if no Alpha channel is available). [select]",
                                                            "enum": [
                                                              "",
                                                              "black",
                                                              "white"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "clip": {
                                                            "description": "When converting TIFF to PNG use embedded clipping path to remove background. [bool]",
                                                            "type": "boolean"
                                                          },
                                                          "colorprofile": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "-",
                                                              "ACESCG Linear",
                                                              "AdobeRGB1998",
                                                              "DCI(P3) RGB",
                                                              "Display P3",
                                                              "Generic CMYK Profile",
                                                              "Generic Gray Gamma 2.2 Profile",
                                                              "Generic Gray Profile",
                                                              "Generic Lab Profile",
                                                              "Generic RGB Profile",
                                                              "Generic XYZ Profile",
                                                              "ISOcoated_v2_eci",
                                                              "ITU-2020",
                                                              "ITU-709",
                                                              "ROMM RGB",
                                                              "eciRGB_v2",
                                                              "sRGB Profile",
                                                              "sRGB_IEC61966-2-1_black_scaled"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "colorspace": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "cmyk",
                                                              "srgb"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "dpi": {
                                                            "description": "DPI width x height. [int]",
                                                            "type": "integer"
                                                          },
                                                          "enlarge": {
                                                            "description": "Enlarge output if the original is smaller than the requested size [bool]",
                                                            "type": "boolean"
                                                          },
                                                          "format": {
                                                            "description": "Output format of the thumbnail. [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png",
                                                              "webp"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "jpegquality": {
                                                            "description": "JPEG quality: 1 (worst) to 100 (best). Use 0 to not explicitely set quality. [int]",
                                                            "type": "integer"
                                                          },
                                                          "resize_mode": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "height",
                                                              "max",
                                                              "min",
                                                              "width"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "Set the output size. Use 0 to keep the original size. [int]",
                                                            "type": "integer"
                                                          },
                                                          "size_minimum": {
                                                            "description": "Only produce version if source size (largest dimension, either `width` or `height`) is greater or equal `size_minimum`. [int]",
                                                            "type": "integer"
                                                          },
                                                          "strip": {
                                                            "description": "Strip metadata from thumbnail. [bool]",
                                                            "type": "boolean"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"imageconverter:browserthumbs\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  }
                                                ]
                                              },
                                              "type": "array"
                                            },
                                            "watermark": {
                                              "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                              "type": "boolean"
                                            }
                                          },
                                          "type": "object"
                                        },
                                        "office": {
                                          "properties": {
                                            "name": {
                                              "description": "Read-only value with the name of the class.",
                                              "type": "string"
                                            },
                                            "rightsmanagement": {
                                              "description": "If set, this version will be configurable in the rights management of fylr.",
                                              "type": "boolean"
                                            },
                                            "sourceversion": {
                                              "description": "The version which is used to produce this version.",
                                              "type": "string"
                                            },
                                            "standard": {
                                              "description": "If set, this version will be included in the standard info.",
                                              "type": "boolean"
                                            },
                                            "uploadenabledextensions": {
                                              "items": {
                                                "description": "Extensions which are allowed in this class for upload.",
                                                "enum": [
                                                  "csv",
                                                  "doc",
                                                  "docx",
                                                  "epub",
                                                  "indd",
                                                  "odp",
                                                  "ods",
                                                  "odt",
                                                  "otf",
                                                  "pdf",
                                                  "ppsx",
                                                  "ppt",
                                                  "pptx",
                                                  "rtf",
                                                  "ttf",
                                                  "txt",
                                                  "xls",
                                                  "xlsx"
                                                ],
                                                "type": "string"
                                              },
                                              "type": "array"
                                            },
                                            "uploadmaxfilesize": {
                                              "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                              "type": "string"
                                            },
                                            "versions": {
                                              "items": {
                                                "oneOf": [
                                                  {
                                                    "description": "Recipe \"officeconverter:preview\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "csv",
                                                                "doc",
                                                                "docx",
                                                                "epub",
                                                                "odp",
                                                                "ods",
                                                                "odt",
                                                                "ppsx",
                                                                "ppt",
                                                                "pptx",
                                                                "rtf",
                                                                "txt",
                                                                "xls",
                                                                "xlsx"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "csv",
                                                            "doc",
                                                            "docx",
                                                            "epub",
                                                            "odp",
                                                            "ods",
                                                            "odt",
                                                            "ppsx",
                                                            "ppt",
                                                            "pptx",
                                                            "rtf",
                                                            "txt",
                                                            "xls",
                                                            "xlsx"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format of the thumbnail [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png",
                                                              "webp"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "resize_mode": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "height",
                                                              "max",
                                                              "min",
                                                              "width"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the output size. [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"officeconverter:preview\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"officeconverter:browserthumbs\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "indd",
                                                                "pdf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "indd",
                                                            "pdf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format of the thumbnail [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png",
                                                              "webp"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the output size. [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"officeconverter:browserthumbs\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"officeconverter:font\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "otf",
                                                                "ttf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "otf",
                                                            "ttf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "size": {
                                                            "description": "set the output size. This will produce a squared preview [int]",
                                                            "type": "integer"
                                                          },
                                                          "text": {
                                                            "description": "text to render on the preview [string]",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"officeconverter:font\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"pdfconverter:pdfpages\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "csv",
                                                                "doc",
                                                                "docx",
                                                                "epub",
                                                                "indd",
                                                                "odp",
                                                                "ods",
                                                                "odt",
                                                                "pdf",
                                                                "ppsx",
                                                                "ppt",
                                                                "pptx",
                                                                "rtf",
                                                                "txt",
                                                                "xls",
                                                                "xlsx"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "csv",
                                                            "doc",
                                                            "docx",
                                                            "epub",
                                                            "indd",
                                                            "odp",
                                                            "ods",
                                                            "odt",
                                                            "pdf",
                                                            "ppsx",
                                                            "ppt",
                                                            "pptx",
                                                            "rtf",
                                                            "txt",
                                                            "xls",
                                                            "xlsx"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "min_size": {
                                                            "description": "Size in pixels of the shortest side of the page.\n [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"pdfconverter:pdfpages\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"officeconverter:pdf\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "csv",
                                                                "doc",
                                                                "docx",
                                                                "epub",
                                                                "odp",
                                                                "ods",
                                                                "odt",
                                                                "ppsx",
                                                                "ppt",
                                                                "pptx",
                                                                "rtf",
                                                                "txt",
                                                                "xls",
                                                                "xlsx"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "csv",
                                                            "doc",
                                                            "docx",
                                                            "epub",
                                                            "odp",
                                                            "ods",
                                                            "odt",
                                                            "ppsx",
                                                            "ppt",
                                                            "pptx",
                                                            "rtf",
                                                            "txt",
                                                            "xls",
                                                            "xlsx"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {},
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"officeconverter:pdf\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  }
                                                ]
                                              },
                                              "type": "array"
                                            },
                                            "watermark": {
                                              "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                              "type": "boolean"
                                            }
                                          },
                                          "type": "object"
                                        },
                                        "video": {
                                          "properties": {
                                            "name": {
                                              "description": "Read-only value with the name of the class.",
                                              "type": "string"
                                            },
                                            "rightsmanagement": {
                                              "description": "If set, this version will be configurable in the rights management of fylr.",
                                              "type": "boolean"
                                            },
                                            "sourceversion": {
                                              "description": "The version which is used to produce this version.",
                                              "type": "string"
                                            },
                                            "standard": {
                                              "description": "If set, this version will be included in the standard info.",
                                              "type": "boolean"
                                            },
                                            "uploadenabledextensions": {
                                              "items": {
                                                "description": "Extensions which are allowed in this class for upload.",
                                                "enum": [
                                                  "3gp",
                                                  "asf",
                                                  "avi",
                                                  "flv",
                                                  "hevc",
                                                  "m2v",
                                                  "m4v",
                                                  "mjpeg",
                                                  "mkv",
                                                  "mov",
                                                  "mp4",
                                                  "mpeg",
                                                  "mpg",
                                                  "mts",
                                                  "mxf",
                                                  "ogv",
                                                  "rm",
                                                  "swf",
                                                  "ts",
                                                  "vob",
                                                  "webm",
                                                  "wmv",
                                                  "wtv"
                                                ],
                                                "type": "string"
                                              },
                                              "type": "array"
                                            },
                                            "uploadmaxfilesize": {
                                              "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                              "type": "string"
                                            },
                                            "versions": {
                                              "items": {
                                                "oneOf": [
                                                  {
                                                    "description": "Recipe \"videoconverter:resize\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "3gp",
                                                                "asf",
                                                                "avi",
                                                                "flv",
                                                                "hevc",
                                                                "m2v",
                                                                "m4v",
                                                                "mjpeg",
                                                                "mkv",
                                                                "mov",
                                                                "mp4",
                                                                "mpeg",
                                                                "mpg",
                                                                "mts",
                                                                "mxf",
                                                                "ogv",
                                                                "rm",
                                                                "swf",
                                                                "ts",
                                                                "vob",
                                                                "webm",
                                                                "wmv",
                                                                "wtv"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "3gp",
                                                            "asf",
                                                            "avi",
                                                            "flv",
                                                            "hevc",
                                                            "m2v",
                                                            "m4v",
                                                            "mjpeg",
                                                            "mkv",
                                                            "mov",
                                                            "mp4",
                                                            "mpeg",
                                                            "mpg",
                                                            "mts",
                                                            "mxf",
                                                            "ogv",
                                                            "rm",
                                                            "swf",
                                                            "ts",
                                                            "vob",
                                                            "webm",
                                                            "wmv",
                                                            "wtv"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "ffmpeg_params": {
                                                            "description": "Additional ffmpeg options for the video production, default is: -codec:v libx264 -profile:v high -level 4.1 -preset fast -crf 20 -pix_fmt yuv420p -codec:a aac -b:a 128k -ac 2 -movflags +faststart [string]",
                                                            "type": "string"
                                                          },
                                                          "height": {
                                                            "description": "set the output height [int]",
                                                            "type": "integer"
                                                          },
                                                          "height_minimum": {
                                                            "description": "only produce version if source height is greater or equal height_minimum [int]",
                                                            "type": "integer"
                                                          },
                                                          "timeout": {
                                                            "description": "maximum duration to encode the video, e.g. \"1m\" or \"1h\" [string]",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"videoconverter:resize\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"videoconverter:thumbnail\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "3gp",
                                                                "asf",
                                                                "avi",
                                                                "flv",
                                                                "hevc",
                                                                "m2v",
                                                                "m4v",
                                                                "mjpeg",
                                                                "mkv",
                                                                "mov",
                                                                "mp4",
                                                                "mpeg",
                                                                "mpg",
                                                                "mts",
                                                                "mxf",
                                                                "ogv",
                                                                "rm",
                                                                "swf",
                                                                "ts",
                                                                "vob",
                                                                "webm",
                                                                "wmv",
                                                                "wtv"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "3gp",
                                                            "asf",
                                                            "avi",
                                                            "flv",
                                                            "hevc",
                                                            "m2v",
                                                            "m4v",
                                                            "mjpeg",
                                                            "mkv",
                                                            "mov",
                                                            "mp4",
                                                            "mpeg",
                                                            "mpg",
                                                            "mts",
                                                            "mxf",
                                                            "ogv",
                                                            "rm",
                                                            "swf",
                                                            "ts",
                                                            "vob",
                                                            "webm",
                                                            "wmv",
                                                            "wtv"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "set the format of the target. [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the target size (eg 128) [string]",
                                                            "type": "string"
                                                          },
                                                          "timeout": {
                                                            "description": "maximum duration to produce the thumbnail, e.g. \"1m\" or \"1h\" [string]",
                                                            "type": "string"
                                                          },
                                                          "video-thumb-select": {
                                                            "description": "\"hh:mm:ss.sss\", \"ss.sss\", \"auto\" or \"no-ffmpegthumbnailer\".\n [string]",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"videoconverter:thumbnail\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  }
                                                ]
                                              },
                                              "type": "array"
                                            },
                                            "watermark": {
                                              "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                              "type": "boolean"
                                            }
                                          },
                                          "type": "object"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "custommetadata": {
                                      "properties": {
                                        "extensions": {
                                          "description": "If given, only run the custom metadata if the extension of the original or version matches.",
                                          "items": {
                                            "enum": [
                                              "3gp",
                                              "aac",
                                              "ai",
                                              "aiff",
                                              "arw",
                                              "asf",
                                              "avi",
                                              "avif",
                                              "bmp",
                                              "cr2",
                                              "cr3",
                                              "crw",
                                              "csv",
                                              "dng",
                                              "doc",
                                              "docx",
                                              "dts",
                                              "eps",
                                              "epub",
                                              "flac",
                                              "flv",
                                              "gif",
                                              "heic",
                                              "hevc",
                                              "ico",
                                              "indd",
                                              "jfif",
                                              "jp2",
                                              "jpeg",
                                              "jpg",
                                              "m2v",
                                              "m4a",
                                              "m4v",
                                              "mjpeg",
                                              "mkv",
                                              "mov",
                                              "mp2",
                                              "mp3",
                                              "mp4",
                                              "mpeg",
                                              "mpg",
                                              "mts",
                                              "mxf",
                                              "nef",
                                              "odp",
                                              "ods",
                                              "odt",
                                              "oga",
                                              "ogg",
                                              "ogv",
                                              "opus",
                                              "otf",
                                              "pcd",
                                              "pdf",
                                              "png",
                                              "ppm",
                                              "ppsx",
                                              "ppt",
                                              "pptx",
                                              "psd",
                                              "ra",
                                              "raf",
                                              "rm",
                                              "rtf",
                                              "rw2",
                                              "svg",
                                              "swf",
                                              "tif",
                                              "tiff",
                                              "ts",
                                              "ttf",
                                              "txt",
                                              "vob",
                                              "wav",
                                              "webm",
                                              "webp",
                                              "wma",
                                              "wmf",
                                              "wmv",
                                              "wtv",
                                              "xls",
                                              "xlsx"
                                            ],
                                            "type": "string"
                                          },
                                          "type": "array"
                                        },
                                        "includeversions": {
                                          "description": "If set, the custom metadata is produces not only for originals but also for all versions.",
                                          "type": "boolean"
                                        },
                                        "recipename": {
                                          "description": "Recipe to process the custom metadata.",
                                          "enum": [
                                            "_metadata:ocr"
                                          ],
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "uploadallowunknown": {
                                      "description": "If set, the upload of file types which are not enabled in any \"uploadenabledextensions\", is allowed.",
                                      "type": "boolean"
                                    },
                                    "uploadmaxfilesize": {
                                      "description": "The upload maximum file size (can be overwritten by each class), given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                      "type": "string"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "json"
                                }
                              },
                              "type": "object"
                            },
                            "publish": {
                              "properties": {
                                "collectors": {
                                  "items": {
                                    "properties": {
                                      "display_format": {
                                        "enum": [
                                          "name",
                                          "name_type",
                                          "name_type_doi",
                                          "type"
                                        ],
                                        "type": "string"
                                      },
                                      "displayname": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "internalname": {
                                        "type": "string"
                                      },
                                      "logo": {
                                        "properties": {
                                          "_id": {
                                            "description": "The EAS-ID of the file.",
                                            "type": "integer"
                                          },
                                          "frontend_prefs": {
                                            "additionalProperties": {
                                              "description": "Any value is allowed"
                                            },
                                            "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                            "type": "object"
                                          }
                                        },
                                        "type": "object",
                                        "x-type": "file"
                                      },
                                      "prefix": {
                                        "type": "string"
                                      },
                                      "type": {
                                        "type": "string"
                                      },
                                      "url": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "purge": {
                              "properties": {
                                "allow_purge": {
                                  "type": "boolean"
                                },
                                "purge_storage": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "readonly": {
                              "properties": {
                                "enabled": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "register": {
                              "properties": {
                                "enable": {
                                  "type": "boolean"
                                },
                                "form": {
                                  "properties": {
                                    "address": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "company": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "department": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "displayname": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "first_name": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "last_name": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "phone": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "use_in_user_manager": {
                                      "type": "boolean"
                                    }
                                  },
                                  "type": "object"
                                },
                                "groups": {
                                  "items": {
                                    "properties": {
                                      "group": {
                                        "type": "integer"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "info": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "saml": {
                              "properties": {
                                "cert": {
                                  "type": "string"
                                },
                                "debug": {
                                  "type": "boolean"
                                },
                                "entry_js": {
                                  "type": "string"
                                },
                                "groupmapping": {
                                  "items": {
                                    "properties": {
                                      "group": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "idp_entity_id": {
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "ldap": {
                                  "properties": {
                                    "bindpassword": {
                                      "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                      "type": "string"
                                    },
                                    "bindusername": {
                                      "type": "string"
                                    },
                                    "connections": {
                                      "items": {
                                        "properties": {
                                          "tls_ca_cert": {
                                            "type": "string"
                                          },
                                          "tls_insecure": {
                                            "type": "boolean"
                                          },
                                          "tls_start": {
                                            "type": "boolean"
                                          },
                                          "url": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "type": "array"
                                    },
                                    "groupbasedn": {
                                      "type": "string"
                                    },
                                    "groupfilter": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "loginlink": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "loginlink_internal": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "loginpreferred": {
                                  "type": "boolean"
                                },
                                "loginredirect": {
                                  "type": "boolean"
                                },
                                "signrequest": {
                                  "enum": [
                                    "",
                                    "sha1",
                                    "sha256",
                                    "sha512"
                                  ],
                                  "type": "string"
                                },
                                "sp_entity_id": {
                                  "type": "string"
                                },
                                "url": {
                                  "type": "string"
                                },
                                "usermapping": {
                                  "items": {
                                    "properties": {
                                      "key": {
                                        "enum": [
                                          "address_supplement",
                                          "company",
                                          "country",
                                          "department",
                                          "displayname",
                                          "email",
                                          "first_name",
                                          "house_number",
                                          "last_name",
                                          "login",
                                          "phone",
                                          "postal_code",
                                          "reference",
                                          "state",
                                          "street",
                                          "town"
                                        ],
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "userupdatecolumn": {
                                  "enum": [
                                    "email",
                                    "login",
                                    "reference"
                                  ],
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "transition_webhook": {
                              "properties": {
                                "webhooks": {
                                  "items": {
                                    "properties": {
                                      "include_access_token": {
                                        "type": "boolean"
                                      },
                                      "name": {
                                        "type": "string"
                                      },
                                      "secret": {
                                        "type": "string"
                                      },
                                      "send_authorization_header": {
                                        "type": "boolean"
                                      },
                                      "timeout": {
                                        "type": "integer"
                                      },
                                      "url": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "two_factor": {
                              "properties": {
                                "allow_password_grant": {
                                  "type": "boolean"
                                },
                                "enabled": {
                                  "type": "boolean"
                                },
                                "methods": {
                                  "items": {
                                    "enum": [
                                      "email",
                                      "passkey",
                                      "totp"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "user": {
                              "properties": {
                                "copy_to_event": {
                                  "items": {
                                    "enum": [
                                      "address_supplement",
                                      "company",
                                      "country",
                                      "department",
                                      "first_name",
                                      "house_number",
                                      "last_name",
                                      "login",
                                      "phone",
                                      "postal_code",
                                      "reference",
                                      "state",
                                      "street",
                                      "town"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "default_delete_policy": {
                                  "enum": [
                                    "archive",
                                    "ask",
                                    "delete"
                                  ],
                                  "type": "string"
                                },
                                "user_in_event_group": {
                                  "items": {
                                    "enum": [
                                      "ADMIN",
                                      "DOWNLOAD",
                                      "EXPORT",
                                      "FRONTEND",
                                      "LOGIN_LOGOUT",
                                      "SYSTEM",
                                      "TASK",
                                      "UPLOAD"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "webdav": {
                              "properties": {
                                "hotfolder": {
                                  "type": "boolean"
                                },
                                "hotfolder_wait_sec": {
                                  "type": "integer"
                                },
                                "read_write_access": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            }
                          },
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Write all base configuration",
        "tags": [
          "config"
        ],
        "x-path": "config",
        "parameters": [
          {
            "name": "save",
            "in": "query",
            "description": "If set to `ignore_errors`, the save persists the config despite\nrecoverable (\"savable\") errors in the base config, such as an LDAP\nconnection that fails to dial. A non-savable error still aborts the\nsave. Implied when `confirm=yes`.\n",
            "schema": {
              "type": "string",
              "enum": [
                "ignore_errors"
              ]
            }
          },
          {
            "name": "confirm",
            "in": "query",
            "description": "Set to `yes` to acknowledge a pending confirmation (HTTP 202) task and\nproceed with the save. When `confirm=yes`, config errors are also\nignored (equivalent to `save=ignore_errors`).\n",
            "schema": {
              "type": "string",
              "enum": [
                "yes"
              ]
            }
          },
          {
            "name": "reindex",
            "in": "query",
            "description": "Answer to the re-index confirmation raised when the frontend or\ndatabase languages change (`system.languages`). `skip` = no re-index;\n`reindex` = re-index in the background; `reindex_block` = re-index and\ntemporarily lock the frontend. Omitted = no re-index requested.\n",
            "schema": {
              "type": "string",
              "enum": [
                "skip",
                "reindex",
                "reindex_block"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "plugin": {
                    "properties": {
                      "formula-columns": {
                        "properties": {
                          "config": {
                            "properties": {
                              "api_user": {
                                "$ref": "#/components/schemas/user_config",
                                "type": "object",
                                "x-type": "user"
                              }
                            },
                            "type": "object"
                          }
                        },
                        "type": "object"
                      }
                    },
                    "type": "object"
                  },
                  "system": {
                    "properties": {
                      "config": {
                        "properties": {
                          "appearance": {
                            "properties": {
                              "background_color": {
                                "type": "string"
                              },
                              "brand_color": {
                                "type": "string"
                              },
                              "favicon": {
                                "properties": {
                                  "_id": {
                                    "description": "The EAS-ID of the file.",
                                    "type": "integer"
                                  },
                                  "frontend_prefs": {
                                    "additionalProperties": {
                                      "description": "Any value is allowed"
                                    },
                                    "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                    "type": "object"
                                  }
                                },
                                "type": "object",
                                "x-type": "file"
                              },
                              "login_background": {
                                "properties": {
                                  "_id": {
                                    "description": "The EAS-ID of the file.",
                                    "type": "integer"
                                  },
                                  "frontend_prefs": {
                                    "additionalProperties": {
                                      "description": "Any value is allowed"
                                    },
                                    "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                    "type": "object"
                                  }
                                },
                                "type": "object",
                                "x-type": "file"
                              },
                              "logo": {
                                "properties": {
                                  "_id": {
                                    "description": "The EAS-ID of the file.",
                                    "type": "integer"
                                  },
                                  "frontend_prefs": {
                                    "additionalProperties": {
                                      "description": "Any value is allowed"
                                    },
                                    "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                    "type": "object"
                                  }
                                },
                                "type": "object",
                                "x-type": "file"
                              },
                              "logo_external_url": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "tag_colors": {
                                "items": {
                                  "properties": {
                                    "tag_color": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "tag_icons": {
                                "items": {
                                  "properties": {
                                    "fa-icon": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "welcome_splash": {
                                "enum": [
                                  "custom_logo",
                                  "fylr",
                                  "off"
                                ],
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "colorprofiles": {
                            "properties": {
                              "profiles": {
                                "items": {
                                  "properties": {
                                    "profile": {
                                      "properties": {
                                        "_id": {
                                          "description": "The EAS-ID of the file.",
                                          "type": "integer"
                                        },
                                        "frontend_prefs": {
                                          "additionalProperties": {
                                            "description": "Any value is allowed"
                                          },
                                          "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                          "type": "object"
                                        }
                                      },
                                      "type": "object",
                                      "x-type": "file"
                                    },
                                    "profilename": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "custom_data_type_updater": {
                            "properties": {
                              "active": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "custom_version_presets": {
                            "properties": {
                              "value": {
                                "properties": {
                                  "presets": {
                                    "description": "Named presets of on-demand custom-version options. Each preset is offered in the download dialog and can be requested on export by name (an export version with `type` `custom` and `custom_version_preset` set to the preset's `name`).",
                                    "items": {
                                      "properties": {
                                        "custom": {
                                          "$ref": "#/components/schemas/ExportCustomVersion"
                                        },
                                        "displayname": {
                                          "type": "object",
                                          "properties": {
                                            "de-DE": {
                                              "type": "string"
                                            },
                                            "en-US": {
                                              "type": "string"
                                            }
                                          },
                                          "example": {
                                            "de-DE": "Deutscher text",
                                            "en-US": "English text"
                                          }
                                        },
                                        "name": {
                                          "description": "Unique name of the preset. Referenced on export via `custom_version_preset` and used in place of `custom` in the produced file name.",
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "type": "array"
                                  }
                                },
                                "type": "object",
                                "x-type": "json"
                              }
                            },
                            "type": "object"
                          },
                          "deep_link_access": {
                            "properties": {
                              "allow_access_by_column": {
                                "type": "boolean"
                              },
                              "allow_access_by_id": {
                                "type": "boolean"
                              },
                              "enabled": {
                                "type": "boolean"
                              },
                              "iiif_default_links": {
                                "type": "boolean"
                              },
                              "iiif_links": {
                                "items": {
                                  "properties": {
                                    "html_code": {
                                      "type": "string"
                                    },
                                    "label": {
                                      "properties": {
                                        "de-DE": {
                                          "type": "string"
                                        },
                                        "en-US": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "iiif_required_statement": {
                                "properties": {
                                  "label": {
                                    "properties": {
                                      "de-DE": {
                                        "type": "string"
                                      },
                                      "en-US": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "value": {
                                    "properties": {
                                      "de-DE": {
                                        "type": "string"
                                      },
                                      "en-US": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  }
                                },
                                "type": "object"
                              },
                              "include_parents": {
                                "type": "boolean"
                              },
                              "merge_linked_objects": {
                                "enum": [
                                  "all",
                                  "in_main_search",
                                  "none",
                                  "not_in_main_search",
                                  "not_in_main_search_unless_reverse"
                                ],
                                "type": "string"
                              },
                              "merge_max_depth": {
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "detail_deep_link": {
                            "properties": {
                              "use_system_object_id": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "email": {
                            "properties": {
                              "admin_emails": {
                                "items": {
                                  "properties": {
                                    "email": {
                                      "format": "email",
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "from": {
                                "format": "email",
                                "type": "string"
                              },
                              "signature": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "type": "object"
                          },
                          "email_server": {
                            "properties": {
                              "cram_md5_auth": {
                                "properties": {
                                  "password": {
                                    "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                    "type": "string"
                                  },
                                  "username": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "helo_domain": {
                                "type": "string"
                              },
                              "insecure_skip_verify": {
                                "type": "boolean"
                              },
                              "login_auth": {
                                "properties": {
                                  "password": {
                                    "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                    "type": "string"
                                  },
                                  "username": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "plain_auth": {
                                "properties": {
                                  "identity": {
                                    "type": "string"
                                  },
                                  "password": {
                                    "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                    "type": "string"
                                  },
                                  "username": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "server_addr": {
                                "type": "string"
                              },
                              "type": {
                                "enum": [
                                  "off",
                                  "starttls",
                                  "tls"
                                ],
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "export": {
                            "properties": {
                              "xslts": {
                                "items": {
                                  "properties": {
                                    "content_type": {
                                      "type": "string"
                                    },
                                    "description": {
                                      "properties": {
                                        "de-DE": {
                                          "type": "string"
                                        },
                                        "en-US": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "displayname": {
                                      "properties": {
                                        "de-DE": {
                                          "type": "string"
                                        },
                                        "en-US": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "namespace": {
                                      "type": "string"
                                    },
                                    "oai_pmh_prefix": {
                                      "type": "string"
                                    },
                                    "schema": {
                                      "type": "string"
                                    },
                                    "use_for_api_objects": {
                                      "type": "boolean"
                                    },
                                    "use_for_oai_pmh": {
                                      "type": "boolean"
                                    },
                                    "xpath_query": {
                                      "type": "string"
                                    },
                                    "xslt": {
                                      "properties": {
                                        "_id": {
                                          "description": "The EAS-ID of the file.",
                                          "type": "integer"
                                        },
                                        "frontend_prefs": {
                                          "additionalProperties": {
                                            "description": "Any value is allowed"
                                          },
                                          "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                          "type": "object"
                                        }
                                      },
                                      "type": "object",
                                      "x-type": "file"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "export_scheduler": {
                            "properties": {
                              "active": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "file_url_expire": {
                            "properties": {
                              "deep_link_days": {
                                "type": "integer"
                              },
                              "default_days": {
                                "type": "integer"
                              },
                              "max_days": {
                                "type": "integer"
                              },
                              "oai_pmh_days": {
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "indexer": {
                            "properties": {
                              "default_analyzer": {
                                "properties": {
                                  "icu_folding": {
                                    "type": "boolean"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "type": "object"
                          },
                          "janitor": {
                            "properties": {
                              "active": {
                                "type": "boolean"
                              },
                              "event_remote_addr_expire_days": {
                                "type": "integer"
                              },
                              "events": {
                                "properties": {
                                  "expire_days_ADMIN": {
                                    "type": "integer"
                                  },
                                  "expire_days_DOWNLOAD": {
                                    "type": "integer"
                                  },
                                  "expire_days_EXPORT": {
                                    "type": "integer"
                                  },
                                  "expire_days_FRONTEND": {
                                    "type": "integer"
                                  },
                                  "expire_days_INDEX": {
                                    "type": "integer"
                                  },
                                  "expire_days_LOGIN_LOGOUT": {
                                    "type": "integer"
                                  },
                                  "expire_days_PLUGIN": {
                                    "type": "integer"
                                  },
                                  "expire_days_SYSTEM": {
                                    "type": "integer"
                                  },
                                  "expire_days_TASK": {
                                    "type": "integer"
                                  },
                                  "expire_days_UPLOAD": {
                                    "type": "integer"
                                  }
                                },
                                "type": "object"
                              },
                              "file_expire_days": {
                                "type": "integer"
                              },
                              "object_and_file_removal": {
                                "properties": {
                                  "allow_overwrite": {
                                    "type": "boolean"
                                  },
                                  "file_link_delete": {
                                    "properties": {
                                      "keep_count_history_versions": {
                                        "type": "integer"
                                      },
                                      "keep_days_history_versions": {
                                        "type": "integer"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "object_purge": {
                                    "properties": {
                                      "min_deleted_days": {
                                        "type": "integer"
                                      }
                                    },
                                    "type": "object"
                                  }
                                },
                                "type": "object"
                              },
                              "users": {
                                "properties": {
                                  "archive_nonactive_after_days": {
                                    "type": "integer"
                                  },
                                  "archive_types": {
                                    "items": {
                                      "enum": [
                                        "anonymous",
                                        "easydb",
                                        "easydb_self_register",
                                        "ldap",
                                        "sso"
                                      ],
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "delete_archived_after_days": {
                                    "type": "integer"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "type": "object"
                          },
                          "languages": {
                            "properties": {
                              "database": {
                                "items": {
                                  "properties": {
                                    "analyzer": {
                                      "properties": {
                                        "icu_folding": {
                                          "type": "boolean"
                                        },
                                        "synonyms": {
                                          "type": "string"
                                        },
                                        "synonyms_file": {
                                          "properties": {
                                            "_id": {
                                              "description": "The EAS-ID of the file.",
                                              "type": "integer"
                                            },
                                            "frontend_prefs": {
                                              "additionalProperties": {
                                                "description": "Any value is allowed"
                                              },
                                              "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                              "type": "object"
                                            }
                                          },
                                          "type": "object",
                                          "x-type": "file"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "date_format": {
                                      "enum": [
                                        "ca",
                                        "cldr",
                                        "da",
                                        "de",
                                        "us"
                                      ],
                                      "type": "string"
                                    },
                                    "displayname": {
                                      "properties": {
                                        "de-DE": {
                                          "type": "string"
                                        },
                                        "en-US": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "number_format": {
                                      "enum": [
                                        "ca",
                                        "cldr",
                                        "de",
                                        "fi",
                                        "it",
                                        "us"
                                      ],
                                      "type": "string"
                                    },
                                    "time_format": {
                                      "enum": [
                                        "cldr",
                                        "da",
                                        "de",
                                        "us"
                                      ],
                                      "type": "string"
                                    },
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "frontend": {
                                "items": {
                                  "enum": [
                                    "da-DK",
                                    "de-DE",
                                    "en-US",
                                    "fi-FI",
                                    "fr-FR",
                                    "it-IT",
                                    "ru-RU",
                                    "sv-SE",
                                    "tvl-TV",
                                    "uz-UZ"
                                  ],
                                  "type": "string"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "ldap": {
                            "properties": {
                              "bindpassword": {
                                "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                "type": "string"
                              },
                              "bindusername": {
                                "type": "string"
                              },
                              "connections": {
                                "items": {
                                  "properties": {
                                    "tls_ca_cert": {
                                      "type": "string"
                                    },
                                    "tls_insecure": {
                                      "type": "boolean"
                                    },
                                    "tls_start": {
                                      "type": "boolean"
                                    },
                                    "url": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "debug": {
                                "type": "boolean"
                              },
                              "groupbasedn": {
                                "type": "string"
                              },
                              "groupfilter": {
                                "type": "string"
                              },
                              "groupmapping": {
                                "items": {
                                  "properties": {
                                    "group": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "userbasedn": {
                                "type": "string"
                              },
                              "userfilter": {
                                "type": "string"
                              },
                              "usermapping": {
                                "items": {
                                  "properties": {
                                    "key": {
                                      "enum": [
                                        "address_supplement",
                                        "company",
                                        "country",
                                        "department",
                                        "displayname",
                                        "email",
                                        "first_name",
                                        "house_number",
                                        "last_name",
                                        "login",
                                        "phone",
                                        "postal_code",
                                        "reference",
                                        "state",
                                        "street",
                                        "town"
                                      ],
                                      "type": "string"
                                    },
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "userupdatecolumn": {
                                "enum": [
                                  "email",
                                  "login",
                                  "reference"
                                ],
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "license": {
                            "properties": {
                              "license": {
                                "$ref": "#/components/schemas/License",
                                "type": "object",
                                "x-type": "license"
                              }
                            },
                            "type": "object"
                          },
                          "loca": {
                            "properties": {
                              "google_csv": {
                                "items": {
                                  "properties": {
                                    "gid": {
                                      "type": "integer"
                                    },
                                    "key": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "google_overload_csv": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "location_defaults": {
                            "properties": {
                              "backups": {
                                "description": "Name of storage location as defined in the location manager",
                                "enum": [
                                  "file"
                                ],
                                "nullable": true,
                                "type": "string"
                              },
                              "originals": {
                                "description": "Name of storage location as defined in the location manager",
                                "enum": [
                                  "file"
                                ],
                                "nullable": true,
                                "type": "string"
                              },
                              "versions": {
                                "description": "Name of storage location as defined in the location manager",
                                "enum": [
                                  "file"
                                ],
                                "nullable": true,
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "logging": {
                            "properties": {
                              "level": {
                                "enum": [
                                  "",
                                  "debug",
                                  "error",
                                  "info",
                                  "trace",
                                  "warn"
                                ],
                                "type": "string"
                              },
                              "timings": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "login": {
                            "properties": {
                              "guest": {
                                "type": "boolean"
                              },
                              "info": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "keep_login": {
                                "enum": [
                                  "30d",
                                  "7d",
                                  "off"
                                ],
                                "type": "string"
                              },
                              "label": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "placeholder": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "type": "object"
                          },
                          "name": {
                            "properties": {
                              "description": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "internal_name": {
                                "type": "string"
                              },
                              "title": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "type": "object"
                          },
                          "notification_scheduler": {
                            "properties": {
                              "active": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "oai_pmh": {
                            "properties": {
                              "admin_email": {
                                "items": {
                                  "properties": {
                                    "email": {
                                      "format": "email",
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "enabled": {
                                "type": "boolean"
                              },
                              "include_parents": {
                                "type": "boolean"
                              },
                              "merge_linked_objects": {
                                "enum": [
                                  "all",
                                  "in_main_search",
                                  "none",
                                  "not_in_main_search",
                                  "not_in_main_search_unless_reverse"
                                ],
                                "type": "string"
                              },
                              "merge_max_depth": {
                                "type": "integer"
                              },
                              "namespace_identifier": {
                                "type": "string"
                              },
                              "records_limit": {
                                "type": "integer"
                              },
                              "repository_name": {
                                "type": "string"
                              },
                              "tagfilter_deleted": {
                                "description": "Tag filter definition with any, all and not",
                                "properties": {
                                  "all": {
                                    "items": {
                                      "description": "List of tag ids which are all required",
                                      "type": "integer"
                                    },
                                    "type": "array"
                                  },
                                  "any": {
                                    "items": {
                                      "description": "List of tag ids of which at least one is required to match",
                                      "type": "integer"
                                    },
                                    "type": "array"
                                  },
                                  "not": {
                                    "items": {
                                      "description": "List of tag ids which must not match",
                                      "type": "integer"
                                    },
                                    "type": "array"
                                  }
                                },
                                "type": "object"
                              },
                              "tagfilter_sets": {
                                "items": {
                                  "properties": {
                                    "set_name": {
                                      "type": "string"
                                    },
                                    "tagfilter": {
                                      "description": "Tag filter definition with any, all and not",
                                      "properties": {
                                        "all": {
                                          "items": {
                                            "description": "List of tag ids which are all required",
                                            "type": "integer"
                                          },
                                          "type": "array"
                                        },
                                        "any": {
                                          "items": {
                                            "description": "List of tag ids of which at least one is required to match",
                                            "type": "integer"
                                          },
                                          "type": "array"
                                        },
                                        "not": {
                                          "items": {
                                            "description": "List of tag ids which must not match",
                                            "type": "integer"
                                          },
                                          "type": "array"
                                        }
                                      },
                                      "type": "object"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "oauth2": {
                            "properties": {
                              "clients": {
                                "items": {
                                  "properties": {
                                    "name": {
                                      "type": "string"
                                    },
                                    "redirect_uris": {
                                      "items": {
                                        "properties": {
                                          "url": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "type": "array"
                                    },
                                    "secret": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "expirations": {
                                "properties": {
                                  "access_token": {
                                    "type": "string"
                                  },
                                  "refresh_token": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "type": "object"
                          },
                          "objectstore": {
                            "properties": {
                              "instance": {
                                "type": "string"
                              },
                              "server": {
                                "type": "string"
                              },
                              "uid": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "openapi_spec_endpoint": {
                            "properties": {
                              "active": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "openid": {
                            "properties": {
                              "userinfo": {
                                "items": {
                                  "enum": [
                                    "address_supplement",
                                    "company",
                                    "country",
                                    "department",
                                    "displayname",
                                    "email",
                                    "first_name",
                                    "house_number",
                                    "last_name",
                                    "phone",
                                    "postal_code",
                                    "state",
                                    "street",
                                    "town"
                                  ],
                                  "type": "string"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "password": {
                            "properties": {
                              "blockclient": {
                                "properties": {
                                  "attempts": {
                                    "type": "integer"
                                  },
                                  "minutes": {
                                    "type": "integer"
                                  }
                                },
                                "type": "object"
                              },
                              "check": {
                                "items": {
                                  "properties": {
                                    "regexp": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "hint": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "showforgot": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "produce_config": {
                            "properties": {
                              "value": {
                                "properties": {
                                  "classes": {
                                    "description": "The produce config defines the renditions (preview versions) produce by the file workers. It includes the parameters for the recipes and defines file extension based routing.",
                                    "properties": {
                                      "audio": {
                                        "properties": {
                                          "name": {
                                            "description": "Read-only value with the name of the class.",
                                            "type": "string"
                                          },
                                          "rightsmanagement": {
                                            "description": "If set, this version will be configurable in the rights management of fylr.",
                                            "type": "boolean"
                                          },
                                          "sourceversion": {
                                            "description": "The version which is used to produce this version.",
                                            "type": "string"
                                          },
                                          "standard": {
                                            "description": "If set, this version will be included in the standard info.",
                                            "type": "boolean"
                                          },
                                          "uploadenabledextensions": {
                                            "items": {
                                              "description": "Extensions which are allowed in this class for upload.",
                                              "enum": [
                                                "aac",
                                                "aiff",
                                                "dts",
                                                "flac",
                                                "m4a",
                                                "mp2",
                                                "mp3",
                                                "oga",
                                                "ogg",
                                                "opus",
                                                "ra",
                                                "wav",
                                                "wma"
                                              ],
                                              "type": "string"
                                            },
                                            "type": "array"
                                          },
                                          "uploadmaxfilesize": {
                                            "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                            "type": "string"
                                          },
                                          "versions": {
                                            "items": {
                                              "oneOf": [
                                                {
                                                  "description": "Recipe \"audioconverter:preview\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "aac",
                                                              "aiff",
                                                              "dts",
                                                              "flac",
                                                              "m4a",
                                                              "mp2",
                                                              "mp3",
                                                              "oga",
                                                              "ogg",
                                                              "opus",
                                                              "ra",
                                                              "wav",
                                                              "wma"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "aac",
                                                          "aiff",
                                                          "dts",
                                                          "flac",
                                                          "m4a",
                                                          "mp2",
                                                          "mp3",
                                                          "oga",
                                                          "ogg",
                                                          "opus",
                                                          "ra",
                                                          "wav",
                                                          "wma"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "format": {
                                                          "description": "output format of the thumbnail [select]",
                                                          "enum": [
                                                            "jpg",
                                                            "png"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "resize_mode": {
                                                          "description": " [select]",
                                                          "enum": [
                                                            "",
                                                            "height",
                                                            "max",
                                                            "min",
                                                            "width"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "size": {
                                                          "description": "set the output size. [int]",
                                                          "type": "integer"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"audioconverter:preview\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                },
                                                {
                                                  "description": "Recipe \"audioconverter:snippet\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "aac",
                                                              "aiff",
                                                              "dts",
                                                              "flac",
                                                              "m4a",
                                                              "mp2",
                                                              "mp3",
                                                              "oga",
                                                              "ogg",
                                                              "opus",
                                                              "ra",
                                                              "wav",
                                                              "wma"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "aac",
                                                          "aiff",
                                                          "dts",
                                                          "flac",
                                                          "m4a",
                                                          "mp2",
                                                          "mp3",
                                                          "oga",
                                                          "ogg",
                                                          "opus",
                                                          "ra",
                                                          "wav",
                                                          "wma"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "end": {
                                                          "description": "timestamp to end snippet [string]",
                                                          "type": "string"
                                                        },
                                                        "format": {
                                                          "description": " [string]",
                                                          "type": "string"
                                                        },
                                                        "start": {
                                                          "description": "timestamp to start snippet [string]",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"audioconverter:snippet\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                },
                                                {
                                                  "description": "Recipe \"audioconverter:convert\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "aac",
                                                              "aiff",
                                                              "dts",
                                                              "flac",
                                                              "m4a",
                                                              "mp2",
                                                              "mp3",
                                                              "oga",
                                                              "ogg",
                                                              "opus",
                                                              "ra",
                                                              "wav",
                                                              "wma"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "aac",
                                                          "aiff",
                                                          "dts",
                                                          "flac",
                                                          "m4a",
                                                          "mp2",
                                                          "mp3",
                                                          "oga",
                                                          "ogg",
                                                          "opus",
                                                          "ra",
                                                          "wav",
                                                          "wma"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "format": {
                                                          "description": "output format [select]",
                                                          "enum": [
                                                            "aac"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"audioconverter:convert\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                }
                                              ]
                                            },
                                            "type": "array"
                                          },
                                          "watermark": {
                                            "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                            "type": "boolean"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "image": {
                                        "properties": {
                                          "name": {
                                            "description": "Read-only value with the name of the class.",
                                            "type": "string"
                                          },
                                          "rightsmanagement": {
                                            "description": "If set, this version will be configurable in the rights management of fylr.",
                                            "type": "boolean"
                                          },
                                          "sourceversion": {
                                            "description": "The version which is used to produce this version.",
                                            "type": "string"
                                          },
                                          "standard": {
                                            "description": "If set, this version will be included in the standard info.",
                                            "type": "boolean"
                                          },
                                          "uploadenabledextensions": {
                                            "items": {
                                              "description": "Extensions which are allowed in this class for upload.",
                                              "enum": [
                                                "ai",
                                                "arw",
                                                "avif",
                                                "bmp",
                                                "cr2",
                                                "cr3",
                                                "crw",
                                                "dng",
                                                "eps",
                                                "gif",
                                                "heic",
                                                "ico",
                                                "jfif",
                                                "jp2",
                                                "jpeg",
                                                "jpg",
                                                "nef",
                                                "pcd",
                                                "png",
                                                "ppm",
                                                "psd",
                                                "raf",
                                                "rw2",
                                                "svg",
                                                "tif",
                                                "tiff",
                                                "webp",
                                                "wmf"
                                              ],
                                              "type": "string"
                                            },
                                            "type": "array"
                                          },
                                          "uploadmaxfilesize": {
                                            "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                            "type": "string"
                                          },
                                          "versions": {
                                            "items": {
                                              "oneOf": [
                                                {
                                                  "description": "Recipe \"imageconverter:vectortosvg\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "ai",
                                                              "eps",
                                                              "wmf"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "ai",
                                                          "eps",
                                                          "wmf"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {},
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"imageconverter:vectortosvg\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                },
                                                {
                                                  "description": "Recipe \"imageconverter:browserthumbs\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "ai",
                                                              "arw",
                                                              "avif",
                                                              "bmp",
                                                              "cr2",
                                                              "cr3",
                                                              "crw",
                                                              "dng",
                                                              "eps",
                                                              "gif",
                                                              "heic",
                                                              "ico",
                                                              "jfif",
                                                              "jp2",
                                                              "jpeg",
                                                              "jpg",
                                                              "nef",
                                                              "pcd",
                                                              "png",
                                                              "ppm",
                                                              "psd",
                                                              "raf",
                                                              "rw2",
                                                              "svg",
                                                              "tif",
                                                              "tiff",
                                                              "webp",
                                                              "wmf"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "ai",
                                                          "arw",
                                                          "avif",
                                                          "bmp",
                                                          "cr2",
                                                          "cr3",
                                                          "crw",
                                                          "dng",
                                                          "eps",
                                                          "gif",
                                                          "heic",
                                                          "ico",
                                                          "jfif",
                                                          "jp2",
                                                          "jpeg",
                                                          "jpg",
                                                          "nef",
                                                          "pcd",
                                                          "png",
                                                          "ppm",
                                                          "psd",
                                                          "raf",
                                                          "rw2",
                                                          "svg",
                                                          "tif",
                                                          "tiff",
                                                          "webp",
                                                          "wmf"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "background": {
                                                          "description": "For background color, defaults to black (if no Alpha channel is available). [select]",
                                                          "enum": [
                                                            "",
                                                            "black",
                                                            "white"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "clip": {
                                                          "description": "When converting TIFF to PNG use embedded clipping path to remove background. [bool]",
                                                          "type": "boolean"
                                                        },
                                                        "colorprofile": {
                                                          "description": " [select]",
                                                          "enum": [
                                                            "",
                                                            "-",
                                                            "ACESCG Linear",
                                                            "AdobeRGB1998",
                                                            "DCI(P3) RGB",
                                                            "Display P3",
                                                            "Generic CMYK Profile",
                                                            "Generic Gray Gamma 2.2 Profile",
                                                            "Generic Gray Profile",
                                                            "Generic Lab Profile",
                                                            "Generic RGB Profile",
                                                            "Generic XYZ Profile",
                                                            "ISOcoated_v2_eci",
                                                            "ITU-2020",
                                                            "ITU-709",
                                                            "ROMM RGB",
                                                            "eciRGB_v2",
                                                            "sRGB Profile",
                                                            "sRGB_IEC61966-2-1_black_scaled"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "colorspace": {
                                                          "description": " [select]",
                                                          "enum": [
                                                            "",
                                                            "cmyk",
                                                            "srgb"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "dpi": {
                                                          "description": "DPI width x height. [int]",
                                                          "type": "integer"
                                                        },
                                                        "enlarge": {
                                                          "description": "Enlarge output if the original is smaller than the requested size [bool]",
                                                          "type": "boolean"
                                                        },
                                                        "format": {
                                                          "description": "Output format of the thumbnail. [select]",
                                                          "enum": [
                                                            "jpg",
                                                            "png",
                                                            "webp"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "jpegquality": {
                                                          "description": "JPEG quality: 1 (worst) to 100 (best). Use 0 to not explicitely set quality. [int]",
                                                          "type": "integer"
                                                        },
                                                        "resize_mode": {
                                                          "description": " [select]",
                                                          "enum": [
                                                            "",
                                                            "height",
                                                            "max",
                                                            "min",
                                                            "width"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "size": {
                                                          "description": "Set the output size. Use 0 to keep the original size. [int]",
                                                          "type": "integer"
                                                        },
                                                        "size_minimum": {
                                                          "description": "Only produce version if source size (largest dimension, either `width` or `height`) is greater or equal `size_minimum`. [int]",
                                                          "type": "integer"
                                                        },
                                                        "strip": {
                                                          "description": "Strip metadata from thumbnail. [bool]",
                                                          "type": "boolean"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"imageconverter:browserthumbs\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                },
                                                {
                                                  "description": "Recipe \"imageconverter:preview_pool_watermark\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "ai",
                                                              "arw",
                                                              "bmp",
                                                              "cr2",
                                                              "cr3",
                                                              "crw",
                                                              "dng",
                                                              "eps",
                                                              "gif",
                                                              "heic",
                                                              "ico",
                                                              "jfif",
                                                              "jp2",
                                                              "jpeg",
                                                              "jpg",
                                                              "nef",
                                                              "pcd",
                                                              "png",
                                                              "ppm",
                                                              "psd",
                                                              "raf",
                                                              "rw2",
                                                              "svg",
                                                              "tif",
                                                              "tiff",
                                                              "webp",
                                                              "wmf"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "ai",
                                                          "arw",
                                                          "bmp",
                                                          "cr2",
                                                          "cr3",
                                                          "crw",
                                                          "dng",
                                                          "eps",
                                                          "gif",
                                                          "heic",
                                                          "ico",
                                                          "jfif",
                                                          "jp2",
                                                          "jpeg",
                                                          "jpg",
                                                          "nef",
                                                          "pcd",
                                                          "png",
                                                          "ppm",
                                                          "psd",
                                                          "raf",
                                                          "rw2",
                                                          "svg",
                                                          "tif",
                                                          "tiff",
                                                          "webp",
                                                          "wmf"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "format": {
                                                          "description": "output format of the thumbnail [select]",
                                                          "enum": [
                                                            "jpg",
                                                            "png",
                                                            "webp"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "resize_mode": {
                                                          "description": " [select]",
                                                          "enum": [
                                                            "",
                                                            "height",
                                                            "max",
                                                            "min",
                                                            "width"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "size": {
                                                          "description": "set the output size. [int]",
                                                          "type": "integer"
                                                        },
                                                        "size_minimum": {
                                                          "description": "Only produce version if source size (largest dimension, either `width` or `height`) is greater or equal `size_minimum`. [int]",
                                                          "type": "integer"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"imageconverter:preview_pool_watermark\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                }
                                              ]
                                            },
                                            "type": "array"
                                          },
                                          "watermark": {
                                            "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                            "type": "boolean"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "office": {
                                        "properties": {
                                          "name": {
                                            "description": "Read-only value with the name of the class.",
                                            "type": "string"
                                          },
                                          "rightsmanagement": {
                                            "description": "If set, this version will be configurable in the rights management of fylr.",
                                            "type": "boolean"
                                          },
                                          "sourceversion": {
                                            "description": "The version which is used to produce this version.",
                                            "type": "string"
                                          },
                                          "standard": {
                                            "description": "If set, this version will be included in the standard info.",
                                            "type": "boolean"
                                          },
                                          "uploadenabledextensions": {
                                            "items": {
                                              "description": "Extensions which are allowed in this class for upload.",
                                              "enum": [
                                                "csv",
                                                "doc",
                                                "docx",
                                                "epub",
                                                "indd",
                                                "odp",
                                                "ods",
                                                "odt",
                                                "otf",
                                                "pdf",
                                                "ppsx",
                                                "ppt",
                                                "pptx",
                                                "rtf",
                                                "ttf",
                                                "txt",
                                                "xls",
                                                "xlsx"
                                              ],
                                              "type": "string"
                                            },
                                            "type": "array"
                                          },
                                          "uploadmaxfilesize": {
                                            "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                            "type": "string"
                                          },
                                          "versions": {
                                            "items": {
                                              "oneOf": [
                                                {
                                                  "description": "Recipe \"officeconverter:font\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "otf",
                                                              "ttf"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "otf",
                                                          "ttf"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "size": {
                                                          "description": "set the output size. This will produce a squared preview [int]",
                                                          "type": "integer"
                                                        },
                                                        "text": {
                                                          "description": "text to render on the preview [string]",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"officeconverter:font\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                },
                                                {
                                                  "description": "Recipe \"officeconverter:pdf\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "csv",
                                                              "doc",
                                                              "docx",
                                                              "epub",
                                                              "odp",
                                                              "ods",
                                                              "odt",
                                                              "ppsx",
                                                              "ppt",
                                                              "pptx",
                                                              "rtf",
                                                              "txt",
                                                              "xls",
                                                              "xlsx"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "csv",
                                                          "doc",
                                                          "docx",
                                                          "epub",
                                                          "odp",
                                                          "ods",
                                                          "odt",
                                                          "ppsx",
                                                          "ppt",
                                                          "pptx",
                                                          "rtf",
                                                          "txt",
                                                          "xls",
                                                          "xlsx"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {},
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"officeconverter:pdf\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                },
                                                {
                                                  "description": "Recipe \"officeconverter:preview\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "csv",
                                                              "doc",
                                                              "docx",
                                                              "epub",
                                                              "odp",
                                                              "ods",
                                                              "odt",
                                                              "ppsx",
                                                              "ppt",
                                                              "pptx",
                                                              "rtf",
                                                              "txt",
                                                              "xls",
                                                              "xlsx"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "csv",
                                                          "doc",
                                                          "docx",
                                                          "epub",
                                                          "odp",
                                                          "ods",
                                                          "odt",
                                                          "ppsx",
                                                          "ppt",
                                                          "pptx",
                                                          "rtf",
                                                          "txt",
                                                          "xls",
                                                          "xlsx"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "format": {
                                                          "description": "output format of the thumbnail [select]",
                                                          "enum": [
                                                            "jpg",
                                                            "png",
                                                            "webp"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "resize_mode": {
                                                          "description": " [select]",
                                                          "enum": [
                                                            "",
                                                            "height",
                                                            "max",
                                                            "min",
                                                            "width"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "size": {
                                                          "description": "set the output size. [int]",
                                                          "type": "integer"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"officeconverter:preview\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                },
                                                {
                                                  "description": "Recipe \"officeconverter:browserthumbs\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "indd",
                                                              "pdf"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "indd",
                                                          "pdf"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "format": {
                                                          "description": "output format of the thumbnail [select]",
                                                          "enum": [
                                                            "jpg",
                                                            "png",
                                                            "webp"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "size": {
                                                          "description": "set the output size. [int]",
                                                          "type": "integer"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"officeconverter:browserthumbs\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                },
                                                {
                                                  "description": "Recipe \"pdfconverter:pdfpages\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "csv",
                                                              "doc",
                                                              "docx",
                                                              "epub",
                                                              "indd",
                                                              "odp",
                                                              "ods",
                                                              "odt",
                                                              "pdf",
                                                              "ppsx",
                                                              "ppt",
                                                              "pptx",
                                                              "rtf",
                                                              "txt",
                                                              "xls",
                                                              "xlsx"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "csv",
                                                          "doc",
                                                          "docx",
                                                          "epub",
                                                          "indd",
                                                          "odp",
                                                          "ods",
                                                          "odt",
                                                          "pdf",
                                                          "ppsx",
                                                          "ppt",
                                                          "pptx",
                                                          "rtf",
                                                          "txt",
                                                          "xls",
                                                          "xlsx"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "min_size": {
                                                          "description": "Size in pixels of the shortest side of the page.\n [int]",
                                                          "type": "integer"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"pdfconverter:pdfpages\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                }
                                              ]
                                            },
                                            "type": "array"
                                          },
                                          "watermark": {
                                            "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                            "type": "boolean"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "video": {
                                        "properties": {
                                          "name": {
                                            "description": "Read-only value with the name of the class.",
                                            "type": "string"
                                          },
                                          "rightsmanagement": {
                                            "description": "If set, this version will be configurable in the rights management of fylr.",
                                            "type": "boolean"
                                          },
                                          "sourceversion": {
                                            "description": "The version which is used to produce this version.",
                                            "type": "string"
                                          },
                                          "standard": {
                                            "description": "If set, this version will be included in the standard info.",
                                            "type": "boolean"
                                          },
                                          "uploadenabledextensions": {
                                            "items": {
                                              "description": "Extensions which are allowed in this class for upload.",
                                              "enum": [
                                                "3gp",
                                                "asf",
                                                "avi",
                                                "flv",
                                                "hevc",
                                                "m2v",
                                                "m4v",
                                                "mjpeg",
                                                "mkv",
                                                "mov",
                                                "mp4",
                                                "mpeg",
                                                "mpg",
                                                "mts",
                                                "mxf",
                                                "ogv",
                                                "rm",
                                                "swf",
                                                "ts",
                                                "vob",
                                                "webm",
                                                "wmv",
                                                "wtv"
                                              ],
                                              "type": "string"
                                            },
                                            "type": "array"
                                          },
                                          "uploadmaxfilesize": {
                                            "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                            "type": "string"
                                          },
                                          "versions": {
                                            "items": {
                                              "oneOf": [
                                                {
                                                  "description": "Recipe \"videoconverter:resize\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "3gp",
                                                              "asf",
                                                              "avi",
                                                              "flv",
                                                              "hevc",
                                                              "m2v",
                                                              "m4v",
                                                              "mjpeg",
                                                              "mkv",
                                                              "mov",
                                                              "mp4",
                                                              "mpeg",
                                                              "mpg",
                                                              "mts",
                                                              "mxf",
                                                              "ogv",
                                                              "rm",
                                                              "swf",
                                                              "ts",
                                                              "vob",
                                                              "webm",
                                                              "wmv",
                                                              "wtv"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "3gp",
                                                          "asf",
                                                          "avi",
                                                          "flv",
                                                          "hevc",
                                                          "m2v",
                                                          "m4v",
                                                          "mjpeg",
                                                          "mkv",
                                                          "mov",
                                                          "mp4",
                                                          "mpeg",
                                                          "mpg",
                                                          "mts",
                                                          "mxf",
                                                          "ogv",
                                                          "rm",
                                                          "swf",
                                                          "ts",
                                                          "vob",
                                                          "webm",
                                                          "wmv",
                                                          "wtv"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "ffmpeg_params": {
                                                          "description": "Additional ffmpeg options for the video production, default is: -codec:v libx264 -profile:v high -level 4.1 -preset fast -crf 20 -pix_fmt yuv420p -codec:a aac -b:a 128k -ac 2 -movflags +faststart [string]",
                                                          "type": "string"
                                                        },
                                                        "height": {
                                                          "description": "set the output height [int]",
                                                          "type": "integer"
                                                        },
                                                        "height_minimum": {
                                                          "description": "only produce version if source height is greater or equal height_minimum [int]",
                                                          "type": "integer"
                                                        },
                                                        "timeout": {
                                                          "description": "maximum duration to encode the video, e.g. \"1m\" or \"1h\" [string]",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"videoconverter:resize\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                },
                                                {
                                                  "description": "Recipe \"videoconverter:thumbnail\"",
                                                  "properties": {
                                                    "custommetadata": {
                                                      "properties": {
                                                        "extensions": {
                                                          "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                          "items": {
                                                            "enum": [
                                                              "3gp",
                                                              "asf",
                                                              "avi",
                                                              "flv",
                                                              "hevc",
                                                              "m2v",
                                                              "m4v",
                                                              "mjpeg",
                                                              "mkv",
                                                              "mov",
                                                              "mp4",
                                                              "mpeg",
                                                              "mpg",
                                                              "mts",
                                                              "mxf",
                                                              "ogv",
                                                              "rm",
                                                              "swf",
                                                              "ts",
                                                              "vob",
                                                              "webm",
                                                              "wmv",
                                                              "wtv"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "type": "array"
                                                        },
                                                        "recipename": {
                                                          "description": "Recipe to process the custom metadata.",
                                                          "enum": [
                                                            "_metadata:ocr"
                                                          ],
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "displayname": {
                                                      "type": "object",
                                                      "properties": {
                                                        "de-DE": {
                                                          "type": "string"
                                                        },
                                                        "en-US": {
                                                          "type": "string"
                                                        }
                                                      },
                                                      "example": {
                                                        "de-DE": "Deutscher text",
                                                        "en-US": "English text"
                                                      }
                                                    },
                                                    "extensions": {
                                                      "items": {
                                                        "enum": [
                                                          "3gp",
                                                          "asf",
                                                          "avi",
                                                          "flv",
                                                          "hevc",
                                                          "m2v",
                                                          "m4v",
                                                          "mjpeg",
                                                          "mkv",
                                                          "mov",
                                                          "mp4",
                                                          "mpeg",
                                                          "mpg",
                                                          "mts",
                                                          "mxf",
                                                          "ogv",
                                                          "rm",
                                                          "swf",
                                                          "ts",
                                                          "vob",
                                                          "webm",
                                                          "wmv",
                                                          "wtv"
                                                        ],
                                                        "type": "string"
                                                      },
                                                      "type": "array"
                                                    },
                                                    "group": {
                                                      "type": "string"
                                                    },
                                                    "name": {
                                                      "type": "string"
                                                    },
                                                    "params": {
                                                      "properties": {
                                                        "format": {
                                                          "description": "set the format of the target. [select]",
                                                          "enum": [
                                                            "jpg",
                                                            "png"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "size": {
                                                          "description": "set the target size (eg 128) [string]",
                                                          "type": "string"
                                                        },
                                                        "timeout": {
                                                          "description": "maximum duration to produce the thumbnail, e.g. \"1m\" or \"1h\" [string]",
                                                          "type": "string"
                                                        },
                                                        "video-thumb-select": {
                                                          "description": "\"hh:mm:ss.sss\", \"ss.sss\", \"auto\" or \"no-ffmpegthumbnailer\".\n [string]",
                                                          "type": "string"
                                                        }
                                                      },
                                                      "type": "object"
                                                    },
                                                    "recipename": {
                                                      "description": "This oneOf block is for \"videoconverter:thumbnail\"",
                                                      "type": "string"
                                                    }
                                                  },
                                                  "type": "object"
                                                }
                                              ]
                                            },
                                            "type": "array"
                                          },
                                          "watermark": {
                                            "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                            "type": "boolean"
                                          }
                                        },
                                        "type": "object"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "custommetadata": {
                                    "properties": {
                                      "extensions": {
                                        "description": "If given, only run the custom metadata if the extension of the original or version matches.",
                                        "items": {
                                          "enum": [
                                            "3gp",
                                            "aac",
                                            "ai",
                                            "aiff",
                                            "arw",
                                            "asf",
                                            "avi",
                                            "avif",
                                            "bmp",
                                            "cr2",
                                            "cr3",
                                            "crw",
                                            "csv",
                                            "dng",
                                            "doc",
                                            "docx",
                                            "dts",
                                            "eps",
                                            "epub",
                                            "flac",
                                            "flv",
                                            "gif",
                                            "heic",
                                            "hevc",
                                            "ico",
                                            "indd",
                                            "jfif",
                                            "jp2",
                                            "jpeg",
                                            "jpg",
                                            "m2v",
                                            "m4a",
                                            "m4v",
                                            "mjpeg",
                                            "mkv",
                                            "mov",
                                            "mp2",
                                            "mp3",
                                            "mp4",
                                            "mpeg",
                                            "mpg",
                                            "mts",
                                            "mxf",
                                            "nef",
                                            "odp",
                                            "ods",
                                            "odt",
                                            "oga",
                                            "ogg",
                                            "ogv",
                                            "opus",
                                            "otf",
                                            "pcd",
                                            "pdf",
                                            "png",
                                            "ppm",
                                            "ppsx",
                                            "ppt",
                                            "pptx",
                                            "psd",
                                            "ra",
                                            "raf",
                                            "rm",
                                            "rtf",
                                            "rw2",
                                            "svg",
                                            "swf",
                                            "tif",
                                            "tiff",
                                            "ts",
                                            "ttf",
                                            "txt",
                                            "vob",
                                            "wav",
                                            "webm",
                                            "webp",
                                            "wma",
                                            "wmf",
                                            "wmv",
                                            "wtv",
                                            "xls",
                                            "xlsx"
                                          ],
                                          "type": "string"
                                        },
                                        "type": "array"
                                      },
                                      "includeversions": {
                                        "description": "If set, the custom metadata is produces not only for originals but also for all versions.",
                                        "type": "boolean"
                                      },
                                      "recipename": {
                                        "description": "Recipe to process the custom metadata.",
                                        "enum": [
                                          "_metadata:ocr"
                                        ],
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "uploadallowunknown": {
                                    "description": "If set, the upload of file types which are not enabled in any \"uploadenabledextensions\", is allowed.",
                                    "type": "boolean"
                                  },
                                  "uploadmaxfilesize": {
                                    "description": "The upload maximum file size (can be overwritten by each class), given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                    "type": "string"
                                  }
                                },
                                "type": "object",
                                "x-type": "json"
                              }
                            },
                            "type": "object"
                          },
                          "publish": {
                            "properties": {
                              "collectors": {
                                "items": {
                                  "properties": {
                                    "display_format": {
                                      "enum": [
                                        "name",
                                        "name_type",
                                        "name_type_doi",
                                        "type"
                                      ],
                                      "type": "string"
                                    },
                                    "displayname": {
                                      "properties": {
                                        "de-DE": {
                                          "type": "string"
                                        },
                                        "en-US": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "internalname": {
                                      "type": "string"
                                    },
                                    "logo": {
                                      "properties": {
                                        "_id": {
                                          "description": "The EAS-ID of the file.",
                                          "type": "integer"
                                        },
                                        "frontend_prefs": {
                                          "additionalProperties": {
                                            "description": "Any value is allowed"
                                          },
                                          "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                          "type": "object"
                                        }
                                      },
                                      "type": "object",
                                      "x-type": "file"
                                    },
                                    "prefix": {
                                      "type": "string"
                                    },
                                    "type": {
                                      "type": "string"
                                    },
                                    "url": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "purge": {
                            "properties": {
                              "allow_purge": {
                                "type": "boolean"
                              },
                              "purge_storage": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "readonly": {
                            "properties": {
                              "enabled": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          },
                          "register": {
                            "properties": {
                              "enable": {
                                "type": "boolean"
                              },
                              "form": {
                                "properties": {
                                  "address": {
                                    "enum": [
                                      "hide",
                                      "require",
                                      "show"
                                    ],
                                    "type": "string"
                                  },
                                  "company": {
                                    "enum": [
                                      "hide",
                                      "require",
                                      "show"
                                    ],
                                    "type": "string"
                                  },
                                  "department": {
                                    "enum": [
                                      "hide",
                                      "require",
                                      "show"
                                    ],
                                    "type": "string"
                                  },
                                  "displayname": {
                                    "enum": [
                                      "hide",
                                      "require",
                                      "show"
                                    ],
                                    "type": "string"
                                  },
                                  "first_name": {
                                    "enum": [
                                      "hide",
                                      "require",
                                      "show"
                                    ],
                                    "type": "string"
                                  },
                                  "last_name": {
                                    "enum": [
                                      "hide",
                                      "require",
                                      "show"
                                    ],
                                    "type": "string"
                                  },
                                  "phone": {
                                    "enum": [
                                      "hide",
                                      "require",
                                      "show"
                                    ],
                                    "type": "string"
                                  },
                                  "use_in_user_manager": {
                                    "type": "boolean"
                                  }
                                },
                                "type": "object"
                              },
                              "groups": {
                                "items": {
                                  "properties": {
                                    "group": {
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "info": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "type": "object"
                          },
                          "saml": {
                            "properties": {
                              "cert": {
                                "type": "string"
                              },
                              "debug": {
                                "type": "boolean"
                              },
                              "entry_js": {
                                "type": "string"
                              },
                              "groupmapping": {
                                "items": {
                                  "properties": {
                                    "group": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "idp_entity_id": {
                                "type": "string"
                              },
                              "key": {
                                "type": "string"
                              },
                              "ldap": {
                                "properties": {
                                  "bindpassword": {
                                    "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                    "type": "string"
                                  },
                                  "bindusername": {
                                    "type": "string"
                                  },
                                  "connections": {
                                    "items": {
                                      "properties": {
                                        "tls_ca_cert": {
                                          "type": "string"
                                        },
                                        "tls_insecure": {
                                          "type": "boolean"
                                        },
                                        "tls_start": {
                                          "type": "boolean"
                                        },
                                        "url": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "groupbasedn": {
                                    "type": "string"
                                  },
                                  "groupfilter": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "loginlink": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "loginlink_internal": {
                                "properties": {
                                  "de-DE": {
                                    "type": "string"
                                  },
                                  "en-US": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "loginpreferred": {
                                "type": "boolean"
                              },
                              "loginredirect": {
                                "type": "boolean"
                              },
                              "signrequest": {
                                "enum": [
                                  "",
                                  "sha1",
                                  "sha256",
                                  "sha512"
                                ],
                                "type": "string"
                              },
                              "sp_entity_id": {
                                "type": "string"
                              },
                              "url": {
                                "type": "string"
                              },
                              "usermapping": {
                                "items": {
                                  "properties": {
                                    "key": {
                                      "enum": [
                                        "address_supplement",
                                        "company",
                                        "country",
                                        "department",
                                        "displayname",
                                        "email",
                                        "first_name",
                                        "house_number",
                                        "last_name",
                                        "login",
                                        "phone",
                                        "postal_code",
                                        "reference",
                                        "state",
                                        "street",
                                        "town"
                                      ],
                                      "type": "string"
                                    },
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "userupdatecolumn": {
                                "enum": [
                                  "email",
                                  "login",
                                  "reference"
                                ],
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "transition_webhook": {
                            "properties": {
                              "webhooks": {
                                "items": {
                                  "properties": {
                                    "include_access_token": {
                                      "type": "boolean"
                                    },
                                    "name": {
                                      "type": "string"
                                    },
                                    "secret": {
                                      "type": "string"
                                    },
                                    "send_authorization_header": {
                                      "type": "boolean"
                                    },
                                    "timeout": {
                                      "type": "integer"
                                    },
                                    "url": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "two_factor": {
                            "properties": {
                              "allow_password_grant": {
                                "type": "boolean"
                              },
                              "enabled": {
                                "type": "boolean"
                              },
                              "methods": {
                                "items": {
                                  "enum": [
                                    "email",
                                    "passkey",
                                    "totp"
                                  ],
                                  "type": "string"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "user": {
                            "properties": {
                              "copy_to_event": {
                                "items": {
                                  "enum": [
                                    "address_supplement",
                                    "company",
                                    "country",
                                    "department",
                                    "first_name",
                                    "house_number",
                                    "last_name",
                                    "login",
                                    "phone",
                                    "postal_code",
                                    "reference",
                                    "state",
                                    "street",
                                    "town"
                                  ],
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "default_delete_policy": {
                                "enum": [
                                  "archive",
                                  "ask",
                                  "delete"
                                ],
                                "type": "string"
                              },
                              "user_in_event_group": {
                                "items": {
                                  "enum": [
                                    "ADMIN",
                                    "DOWNLOAD",
                                    "EXPORT",
                                    "FRONTEND",
                                    "LOGIN_LOGOUT",
                                    "SYSTEM",
                                    "TASK",
                                    "UPLOAD"
                                  ],
                                  "type": "string"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "webdav": {
                            "properties": {
                              "hotfolder": {
                                "type": "boolean"
                              },
                              "hotfolder_wait_sec": {
                                "type": "integer"
                              },
                              "read_write_access": {
                                "type": "boolean"
                              }
                            },
                            "type": "object"
                          }
                        },
                        "type": "object"
                      }
                    },
                    "type": "object"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The response contains the base configuration values.\n",
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "plugin": {
                      "properties": {
                        "formula-columns": {
                          "properties": {
                            "config": {
                              "properties": {
                                "api_user": {
                                  "$ref": "#/components/schemas/user_config",
                                  "type": "object",
                                  "x-type": "user"
                                }
                              },
                              "type": "object"
                            }
                          },
                          "type": "object"
                        }
                      },
                      "type": "object"
                    },
                    "system": {
                      "properties": {
                        "config": {
                          "properties": {
                            "appearance": {
                              "properties": {
                                "background_color": {
                                  "type": "string"
                                },
                                "brand_color": {
                                  "type": "string"
                                },
                                "favicon": {
                                  "properties": {
                                    "_id": {
                                      "description": "The EAS-ID of the file.",
                                      "type": "integer"
                                    },
                                    "frontend_prefs": {
                                      "additionalProperties": {
                                        "description": "Any value is allowed"
                                      },
                                      "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                      "type": "object"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "file"
                                },
                                "login_background": {
                                  "properties": {
                                    "_id": {
                                      "description": "The EAS-ID of the file.",
                                      "type": "integer"
                                    },
                                    "frontend_prefs": {
                                      "additionalProperties": {
                                        "description": "Any value is allowed"
                                      },
                                      "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                      "type": "object"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "file"
                                },
                                "logo": {
                                  "properties": {
                                    "_id": {
                                      "description": "The EAS-ID of the file.",
                                      "type": "integer"
                                    },
                                    "frontend_prefs": {
                                      "additionalProperties": {
                                        "description": "Any value is allowed"
                                      },
                                      "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                      "type": "object"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "file"
                                },
                                "logo_external_url": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "tag_colors": {
                                  "items": {
                                    "properties": {
                                      "tag_color": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "tag_icons": {
                                  "items": {
                                    "properties": {
                                      "fa-icon": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "welcome_splash": {
                                  "enum": [
                                    "custom_logo",
                                    "fylr",
                                    "off"
                                  ],
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "colorprofiles": {
                              "properties": {
                                "profiles": {
                                  "items": {
                                    "properties": {
                                      "profile": {
                                        "properties": {
                                          "_id": {
                                            "description": "The EAS-ID of the file.",
                                            "type": "integer"
                                          },
                                          "frontend_prefs": {
                                            "additionalProperties": {
                                              "description": "Any value is allowed"
                                            },
                                            "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                            "type": "object"
                                          }
                                        },
                                        "type": "object",
                                        "x-type": "file"
                                      },
                                      "profilename": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "custom_data_type_updater": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "custom_version_presets": {
                              "properties": {
                                "value": {
                                  "properties": {
                                    "presets": {
                                      "description": "Named presets of on-demand custom-version options. Each preset is offered in the download dialog and can be requested on export by name (an export version with `type` `custom` and `custom_version_preset` set to the preset's `name`).",
                                      "items": {
                                        "properties": {
                                          "custom": {
                                            "$ref": "#/components/schemas/ExportCustomVersion"
                                          },
                                          "displayname": {
                                            "type": "object",
                                            "properties": {
                                              "de-DE": {
                                                "type": "string"
                                              },
                                              "en-US": {
                                                "type": "string"
                                              }
                                            },
                                            "example": {
                                              "de-DE": "Deutscher text",
                                              "en-US": "English text"
                                            }
                                          },
                                          "name": {
                                            "description": "Unique name of the preset. Referenced on export via `custom_version_preset` and used in place of `custom` in the produced file name.",
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "type": "array"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "json"
                                }
                              },
                              "type": "object"
                            },
                            "deep_link_access": {
                              "properties": {
                                "allow_access_by_column": {
                                  "type": "boolean"
                                },
                                "allow_access_by_id": {
                                  "type": "boolean"
                                },
                                "enabled": {
                                  "type": "boolean"
                                },
                                "iiif_default_links": {
                                  "type": "boolean"
                                },
                                "iiif_links": {
                                  "items": {
                                    "properties": {
                                      "html_code": {
                                        "type": "string"
                                      },
                                      "label": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "iiif_required_statement": {
                                  "properties": {
                                    "label": {
                                      "properties": {
                                        "de-DE": {
                                          "type": "string"
                                        },
                                        "en-US": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "value": {
                                      "properties": {
                                        "de-DE": {
                                          "type": "string"
                                        },
                                        "en-US": {
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    }
                                  },
                                  "type": "object"
                                },
                                "include_parents": {
                                  "type": "boolean"
                                },
                                "merge_linked_objects": {
                                  "enum": [
                                    "all",
                                    "in_main_search",
                                    "none",
                                    "not_in_main_search",
                                    "not_in_main_search_unless_reverse"
                                  ],
                                  "type": "string"
                                },
                                "merge_max_depth": {
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "detail_deep_link": {
                              "properties": {
                                "use_system_object_id": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "email": {
                              "properties": {
                                "admin_emails": {
                                  "items": {
                                    "properties": {
                                      "email": {
                                        "format": "email",
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "from": {
                                  "format": "email",
                                  "type": "string"
                                },
                                "signature": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "email_server": {
                              "properties": {
                                "cram_md5_auth": {
                                  "properties": {
                                    "password": {
                                      "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                      "type": "string"
                                    },
                                    "username": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "helo_domain": {
                                  "type": "string"
                                },
                                "insecure_skip_verify": {
                                  "type": "boolean"
                                },
                                "login_auth": {
                                  "properties": {
                                    "password": {
                                      "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                      "type": "string"
                                    },
                                    "username": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "plain_auth": {
                                  "properties": {
                                    "identity": {
                                      "type": "string"
                                    },
                                    "password": {
                                      "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                      "type": "string"
                                    },
                                    "username": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "server_addr": {
                                  "type": "string"
                                },
                                "type": {
                                  "enum": [
                                    "off",
                                    "starttls",
                                    "tls"
                                  ],
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "export": {
                              "properties": {
                                "xslts": {
                                  "items": {
                                    "properties": {
                                      "content_type": {
                                        "type": "string"
                                      },
                                      "description": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "displayname": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "namespace": {
                                        "type": "string"
                                      },
                                      "oai_pmh_prefix": {
                                        "type": "string"
                                      },
                                      "schema": {
                                        "type": "string"
                                      },
                                      "use_for_api_objects": {
                                        "type": "boolean"
                                      },
                                      "use_for_oai_pmh": {
                                        "type": "boolean"
                                      },
                                      "xpath_query": {
                                        "type": "string"
                                      },
                                      "xslt": {
                                        "properties": {
                                          "_id": {
                                            "description": "The EAS-ID of the file.",
                                            "type": "integer"
                                          },
                                          "frontend_prefs": {
                                            "additionalProperties": {
                                              "description": "Any value is allowed"
                                            },
                                            "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                            "type": "object"
                                          }
                                        },
                                        "type": "object",
                                        "x-type": "file"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "export_scheduler": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "file_url_expire": {
                              "properties": {
                                "deep_link_days": {
                                  "type": "integer"
                                },
                                "default_days": {
                                  "type": "integer"
                                },
                                "max_days": {
                                  "type": "integer"
                                },
                                "oai_pmh_days": {
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "indexer": {
                              "properties": {
                                "default_analyzer": {
                                  "properties": {
                                    "icu_folding": {
                                      "type": "boolean"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "janitor": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                },
                                "event_remote_addr_expire_days": {
                                  "type": "integer"
                                },
                                "events": {
                                  "properties": {
                                    "expire_days_ADMIN": {
                                      "type": "integer"
                                    },
                                    "expire_days_DOWNLOAD": {
                                      "type": "integer"
                                    },
                                    "expire_days_EXPORT": {
                                      "type": "integer"
                                    },
                                    "expire_days_FRONTEND": {
                                      "type": "integer"
                                    },
                                    "expire_days_INDEX": {
                                      "type": "integer"
                                    },
                                    "expire_days_LOGIN_LOGOUT": {
                                      "type": "integer"
                                    },
                                    "expire_days_PLUGIN": {
                                      "type": "integer"
                                    },
                                    "expire_days_SYSTEM": {
                                      "type": "integer"
                                    },
                                    "expire_days_TASK": {
                                      "type": "integer"
                                    },
                                    "expire_days_UPLOAD": {
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "file_expire_days": {
                                  "type": "integer"
                                },
                                "object_and_file_removal": {
                                  "properties": {
                                    "allow_overwrite": {
                                      "type": "boolean"
                                    },
                                    "file_link_delete": {
                                      "properties": {
                                        "keep_count_history_versions": {
                                          "type": "integer"
                                        },
                                        "keep_days_history_versions": {
                                          "type": "integer"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "object_purge": {
                                      "properties": {
                                        "min_deleted_days": {
                                          "type": "integer"
                                        }
                                      },
                                      "type": "object"
                                    }
                                  },
                                  "type": "object"
                                },
                                "users": {
                                  "properties": {
                                    "archive_nonactive_after_days": {
                                      "type": "integer"
                                    },
                                    "archive_types": {
                                      "items": {
                                        "enum": [
                                          "anonymous",
                                          "easydb",
                                          "easydb_self_register",
                                          "ldap",
                                          "sso"
                                        ],
                                        "type": "string"
                                      },
                                      "type": "array"
                                    },
                                    "delete_archived_after_days": {
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "languages": {
                              "properties": {
                                "database": {
                                  "items": {
                                    "properties": {
                                      "analyzer": {
                                        "properties": {
                                          "icu_folding": {
                                            "type": "boolean"
                                          },
                                          "synonyms": {
                                            "type": "string"
                                          },
                                          "synonyms_file": {
                                            "properties": {
                                              "_id": {
                                                "description": "The EAS-ID of the file.",
                                                "type": "integer"
                                              },
                                              "frontend_prefs": {
                                                "additionalProperties": {
                                                  "description": "Any value is allowed"
                                                },
                                                "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                                "type": "object"
                                              }
                                            },
                                            "type": "object",
                                            "x-type": "file"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "date_format": {
                                        "enum": [
                                          "ca",
                                          "cldr",
                                          "da",
                                          "de",
                                          "us"
                                        ],
                                        "type": "string"
                                      },
                                      "displayname": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "number_format": {
                                        "enum": [
                                          "ca",
                                          "cldr",
                                          "de",
                                          "fi",
                                          "it",
                                          "us"
                                        ],
                                        "type": "string"
                                      },
                                      "time_format": {
                                        "enum": [
                                          "cldr",
                                          "da",
                                          "de",
                                          "us"
                                        ],
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "frontend": {
                                  "items": {
                                    "enum": [
                                      "da-DK",
                                      "de-DE",
                                      "en-US",
                                      "fi-FI",
                                      "fr-FR",
                                      "it-IT",
                                      "ru-RU",
                                      "sv-SE",
                                      "tvl-TV",
                                      "uz-UZ"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "ldap": {
                              "properties": {
                                "bindpassword": {
                                  "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                  "type": "string"
                                },
                                "bindusername": {
                                  "type": "string"
                                },
                                "connections": {
                                  "items": {
                                    "properties": {
                                      "tls_ca_cert": {
                                        "type": "string"
                                      },
                                      "tls_insecure": {
                                        "type": "boolean"
                                      },
                                      "tls_start": {
                                        "type": "boolean"
                                      },
                                      "url": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "debug": {
                                  "type": "boolean"
                                },
                                "groupbasedn": {
                                  "type": "string"
                                },
                                "groupfilter": {
                                  "type": "string"
                                },
                                "groupmapping": {
                                  "items": {
                                    "properties": {
                                      "group": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "userbasedn": {
                                  "type": "string"
                                },
                                "userfilter": {
                                  "type": "string"
                                },
                                "usermapping": {
                                  "items": {
                                    "properties": {
                                      "key": {
                                        "enum": [
                                          "address_supplement",
                                          "company",
                                          "country",
                                          "department",
                                          "displayname",
                                          "email",
                                          "first_name",
                                          "house_number",
                                          "last_name",
                                          "login",
                                          "phone",
                                          "postal_code",
                                          "reference",
                                          "state",
                                          "street",
                                          "town"
                                        ],
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "userupdatecolumn": {
                                  "enum": [
                                    "email",
                                    "login",
                                    "reference"
                                  ],
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "license": {
                              "properties": {
                                "license": {
                                  "$ref": "#/components/schemas/License",
                                  "type": "object",
                                  "x-type": "license"
                                }
                              },
                              "type": "object"
                            },
                            "loca": {
                              "properties": {
                                "google_csv": {
                                  "items": {
                                    "properties": {
                                      "gid": {
                                        "type": "integer"
                                      },
                                      "key": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "google_overload_csv": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "location_defaults": {
                              "properties": {
                                "backups": {
                                  "description": "Name of storage location as defined in the location manager",
                                  "enum": [
                                    "file"
                                  ],
                                  "nullable": true,
                                  "type": "string"
                                },
                                "originals": {
                                  "description": "Name of storage location as defined in the location manager",
                                  "enum": [
                                    "file"
                                  ],
                                  "nullable": true,
                                  "type": "string"
                                },
                                "versions": {
                                  "description": "Name of storage location as defined in the location manager",
                                  "enum": [
                                    "file"
                                  ],
                                  "nullable": true,
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "logging": {
                              "properties": {
                                "level": {
                                  "enum": [
                                    "",
                                    "debug",
                                    "error",
                                    "info",
                                    "trace",
                                    "warn"
                                  ],
                                  "type": "string"
                                },
                                "timings": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "login": {
                              "properties": {
                                "guest": {
                                  "type": "boolean"
                                },
                                "info": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "keep_login": {
                                  "enum": [
                                    "30d",
                                    "7d",
                                    "off"
                                  ],
                                  "type": "string"
                                },
                                "label": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "placeholder": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "name": {
                              "properties": {
                                "description": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "internal_name": {
                                  "type": "string"
                                },
                                "title": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "notification_scheduler": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "oai_pmh": {
                              "properties": {
                                "admin_email": {
                                  "items": {
                                    "properties": {
                                      "email": {
                                        "format": "email",
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "enabled": {
                                  "type": "boolean"
                                },
                                "include_parents": {
                                  "type": "boolean"
                                },
                                "merge_linked_objects": {
                                  "enum": [
                                    "all",
                                    "in_main_search",
                                    "none",
                                    "not_in_main_search",
                                    "not_in_main_search_unless_reverse"
                                  ],
                                  "type": "string"
                                },
                                "merge_max_depth": {
                                  "type": "integer"
                                },
                                "namespace_identifier": {
                                  "type": "string"
                                },
                                "records_limit": {
                                  "type": "integer"
                                },
                                "repository_name": {
                                  "type": "string"
                                },
                                "tagfilter_deleted": {
                                  "description": "Tag filter definition with any, all and not",
                                  "properties": {
                                    "all": {
                                      "items": {
                                        "description": "List of tag ids which are all required",
                                        "type": "integer"
                                      },
                                      "type": "array"
                                    },
                                    "any": {
                                      "items": {
                                        "description": "List of tag ids of which at least one is required to match",
                                        "type": "integer"
                                      },
                                      "type": "array"
                                    },
                                    "not": {
                                      "items": {
                                        "description": "List of tag ids which must not match",
                                        "type": "integer"
                                      },
                                      "type": "array"
                                    }
                                  },
                                  "type": "object"
                                },
                                "tagfilter_sets": {
                                  "items": {
                                    "properties": {
                                      "set_name": {
                                        "type": "string"
                                      },
                                      "tagfilter": {
                                        "description": "Tag filter definition with any, all and not",
                                        "properties": {
                                          "all": {
                                            "items": {
                                              "description": "List of tag ids which are all required",
                                              "type": "integer"
                                            },
                                            "type": "array"
                                          },
                                          "any": {
                                            "items": {
                                              "description": "List of tag ids of which at least one is required to match",
                                              "type": "integer"
                                            },
                                            "type": "array"
                                          },
                                          "not": {
                                            "items": {
                                              "description": "List of tag ids which must not match",
                                              "type": "integer"
                                            },
                                            "type": "array"
                                          }
                                        },
                                        "type": "object"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "oauth2": {
                              "properties": {
                                "clients": {
                                  "items": {
                                    "properties": {
                                      "name": {
                                        "type": "string"
                                      },
                                      "redirect_uris": {
                                        "items": {
                                          "properties": {
                                            "url": {
                                              "type": "string"
                                            }
                                          },
                                          "type": "object"
                                        },
                                        "type": "array"
                                      },
                                      "secret": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "expirations": {
                                  "properties": {
                                    "access_token": {
                                      "type": "string"
                                    },
                                    "refresh_token": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "objectstore": {
                              "properties": {
                                "instance": {
                                  "type": "string"
                                },
                                "server": {
                                  "type": "string"
                                },
                                "uid": {
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "openapi_spec_endpoint": {
                              "properties": {
                                "active": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "openid": {
                              "properties": {
                                "userinfo": {
                                  "items": {
                                    "enum": [
                                      "address_supplement",
                                      "company",
                                      "country",
                                      "department",
                                      "displayname",
                                      "email",
                                      "first_name",
                                      "house_number",
                                      "last_name",
                                      "phone",
                                      "postal_code",
                                      "state",
                                      "street",
                                      "town"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "password": {
                              "properties": {
                                "blockclient": {
                                  "properties": {
                                    "attempts": {
                                      "type": "integer"
                                    },
                                    "minutes": {
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "check": {
                                  "items": {
                                    "properties": {
                                      "regexp": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "hint": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "showforgot": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "produce_config": {
                              "properties": {
                                "value": {
                                  "properties": {
                                    "classes": {
                                      "description": "The produce config defines the renditions (preview versions) produce by the file workers. It includes the parameters for the recipes and defines file extension based routing.",
                                      "properties": {
                                        "audio": {
                                          "properties": {
                                            "name": {
                                              "description": "Read-only value with the name of the class.",
                                              "type": "string"
                                            },
                                            "rightsmanagement": {
                                              "description": "If set, this version will be configurable in the rights management of fylr.",
                                              "type": "boolean"
                                            },
                                            "sourceversion": {
                                              "description": "The version which is used to produce this version.",
                                              "type": "string"
                                            },
                                            "standard": {
                                              "description": "If set, this version will be included in the standard info.",
                                              "type": "boolean"
                                            },
                                            "uploadenabledextensions": {
                                              "items": {
                                                "description": "Extensions which are allowed in this class for upload.",
                                                "enum": [
                                                  "aac",
                                                  "aiff",
                                                  "dts",
                                                  "flac",
                                                  "m4a",
                                                  "mp2",
                                                  "mp3",
                                                  "oga",
                                                  "ogg",
                                                  "opus",
                                                  "ra",
                                                  "wav",
                                                  "wma"
                                                ],
                                                "type": "string"
                                              },
                                              "type": "array"
                                            },
                                            "uploadmaxfilesize": {
                                              "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                              "type": "string"
                                            },
                                            "versions": {
                                              "items": {
                                                "oneOf": [
                                                  {
                                                    "description": "Recipe \"audioconverter:convert\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "aac",
                                                                "aiff",
                                                                "dts",
                                                                "flac",
                                                                "m4a",
                                                                "mp2",
                                                                "mp3",
                                                                "oga",
                                                                "ogg",
                                                                "opus",
                                                                "ra",
                                                                "wav",
                                                                "wma"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "aac",
                                                            "aiff",
                                                            "dts",
                                                            "flac",
                                                            "m4a",
                                                            "mp2",
                                                            "mp3",
                                                            "oga",
                                                            "ogg",
                                                            "opus",
                                                            "ra",
                                                            "wav",
                                                            "wma"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format [select]",
                                                            "enum": [
                                                              "aac"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"audioconverter:convert\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"audioconverter:preview\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "aac",
                                                                "aiff",
                                                                "dts",
                                                                "flac",
                                                                "m4a",
                                                                "mp2",
                                                                "mp3",
                                                                "oga",
                                                                "ogg",
                                                                "opus",
                                                                "ra",
                                                                "wav",
                                                                "wma"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "aac",
                                                            "aiff",
                                                            "dts",
                                                            "flac",
                                                            "m4a",
                                                            "mp2",
                                                            "mp3",
                                                            "oga",
                                                            "ogg",
                                                            "opus",
                                                            "ra",
                                                            "wav",
                                                            "wma"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format of the thumbnail [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "resize_mode": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "height",
                                                              "max",
                                                              "min",
                                                              "width"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the output size. [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"audioconverter:preview\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"audioconverter:snippet\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "aac",
                                                                "aiff",
                                                                "dts",
                                                                "flac",
                                                                "m4a",
                                                                "mp2",
                                                                "mp3",
                                                                "oga",
                                                                "ogg",
                                                                "opus",
                                                                "ra",
                                                                "wav",
                                                                "wma"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "aac",
                                                            "aiff",
                                                            "dts",
                                                            "flac",
                                                            "m4a",
                                                            "mp2",
                                                            "mp3",
                                                            "oga",
                                                            "ogg",
                                                            "opus",
                                                            "ra",
                                                            "wav",
                                                            "wma"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "end": {
                                                            "description": "timestamp to end snippet [string]",
                                                            "type": "string"
                                                          },
                                                          "format": {
                                                            "description": " [string]",
                                                            "type": "string"
                                                          },
                                                          "start": {
                                                            "description": "timestamp to start snippet [string]",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"audioconverter:snippet\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  }
                                                ]
                                              },
                                              "type": "array"
                                            },
                                            "watermark": {
                                              "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                              "type": "boolean"
                                            }
                                          },
                                          "type": "object"
                                        },
                                        "image": {
                                          "properties": {
                                            "name": {
                                              "description": "Read-only value with the name of the class.",
                                              "type": "string"
                                            },
                                            "rightsmanagement": {
                                              "description": "If set, this version will be configurable in the rights management of fylr.",
                                              "type": "boolean"
                                            },
                                            "sourceversion": {
                                              "description": "The version which is used to produce this version.",
                                              "type": "string"
                                            },
                                            "standard": {
                                              "description": "If set, this version will be included in the standard info.",
                                              "type": "boolean"
                                            },
                                            "uploadenabledextensions": {
                                              "items": {
                                                "description": "Extensions which are allowed in this class for upload.",
                                                "enum": [
                                                  "ai",
                                                  "arw",
                                                  "avif",
                                                  "bmp",
                                                  "cr2",
                                                  "cr3",
                                                  "crw",
                                                  "dng",
                                                  "eps",
                                                  "gif",
                                                  "heic",
                                                  "ico",
                                                  "jfif",
                                                  "jp2",
                                                  "jpeg",
                                                  "jpg",
                                                  "nef",
                                                  "pcd",
                                                  "png",
                                                  "ppm",
                                                  "psd",
                                                  "raf",
                                                  "rw2",
                                                  "svg",
                                                  "tif",
                                                  "tiff",
                                                  "webp",
                                                  "wmf"
                                                ],
                                                "type": "string"
                                              },
                                              "type": "array"
                                            },
                                            "uploadmaxfilesize": {
                                              "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                              "type": "string"
                                            },
                                            "versions": {
                                              "items": {
                                                "oneOf": [
                                                  {
                                                    "description": "Recipe \"imageconverter:preview_pool_watermark\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "ai",
                                                                "arw",
                                                                "bmp",
                                                                "cr2",
                                                                "cr3",
                                                                "crw",
                                                                "dng",
                                                                "eps",
                                                                "gif",
                                                                "heic",
                                                                "ico",
                                                                "jfif",
                                                                "jp2",
                                                                "jpeg",
                                                                "jpg",
                                                                "nef",
                                                                "pcd",
                                                                "png",
                                                                "ppm",
                                                                "psd",
                                                                "raf",
                                                                "rw2",
                                                                "svg",
                                                                "tif",
                                                                "tiff",
                                                                "webp",
                                                                "wmf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "ai",
                                                            "arw",
                                                            "bmp",
                                                            "cr2",
                                                            "cr3",
                                                            "crw",
                                                            "dng",
                                                            "eps",
                                                            "gif",
                                                            "heic",
                                                            "ico",
                                                            "jfif",
                                                            "jp2",
                                                            "jpeg",
                                                            "jpg",
                                                            "nef",
                                                            "pcd",
                                                            "png",
                                                            "ppm",
                                                            "psd",
                                                            "raf",
                                                            "rw2",
                                                            "svg",
                                                            "tif",
                                                            "tiff",
                                                            "webp",
                                                            "wmf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format of the thumbnail [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png",
                                                              "webp"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "resize_mode": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "height",
                                                              "max",
                                                              "min",
                                                              "width"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the output size. [int]",
                                                            "type": "integer"
                                                          },
                                                          "size_minimum": {
                                                            "description": "Only produce version if source size (largest dimension, either `width` or `height`) is greater or equal `size_minimum`. [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"imageconverter:preview_pool_watermark\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"imageconverter:vectortosvg\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "ai",
                                                                "eps",
                                                                "wmf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "ai",
                                                            "eps",
                                                            "wmf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {},
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"imageconverter:vectortosvg\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"imageconverter:browserthumbs\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "ai",
                                                                "arw",
                                                                "avif",
                                                                "bmp",
                                                                "cr2",
                                                                "cr3",
                                                                "crw",
                                                                "dng",
                                                                "eps",
                                                                "gif",
                                                                "heic",
                                                                "ico",
                                                                "jfif",
                                                                "jp2",
                                                                "jpeg",
                                                                "jpg",
                                                                "nef",
                                                                "pcd",
                                                                "png",
                                                                "ppm",
                                                                "psd",
                                                                "raf",
                                                                "rw2",
                                                                "svg",
                                                                "tif",
                                                                "tiff",
                                                                "webp",
                                                                "wmf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "ai",
                                                            "arw",
                                                            "avif",
                                                            "bmp",
                                                            "cr2",
                                                            "cr3",
                                                            "crw",
                                                            "dng",
                                                            "eps",
                                                            "gif",
                                                            "heic",
                                                            "ico",
                                                            "jfif",
                                                            "jp2",
                                                            "jpeg",
                                                            "jpg",
                                                            "nef",
                                                            "pcd",
                                                            "png",
                                                            "ppm",
                                                            "psd",
                                                            "raf",
                                                            "rw2",
                                                            "svg",
                                                            "tif",
                                                            "tiff",
                                                            "webp",
                                                            "wmf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "background": {
                                                            "description": "For background color, defaults to black (if no Alpha channel is available). [select]",
                                                            "enum": [
                                                              "",
                                                              "black",
                                                              "white"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "clip": {
                                                            "description": "When converting TIFF to PNG use embedded clipping path to remove background. [bool]",
                                                            "type": "boolean"
                                                          },
                                                          "colorprofile": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "-",
                                                              "ACESCG Linear",
                                                              "AdobeRGB1998",
                                                              "DCI(P3) RGB",
                                                              "Display P3",
                                                              "Generic CMYK Profile",
                                                              "Generic Gray Gamma 2.2 Profile",
                                                              "Generic Gray Profile",
                                                              "Generic Lab Profile",
                                                              "Generic RGB Profile",
                                                              "Generic XYZ Profile",
                                                              "ISOcoated_v2_eci",
                                                              "ITU-2020",
                                                              "ITU-709",
                                                              "ROMM RGB",
                                                              "eciRGB_v2",
                                                              "sRGB Profile",
                                                              "sRGB_IEC61966-2-1_black_scaled"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "colorspace": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "cmyk",
                                                              "srgb"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "dpi": {
                                                            "description": "DPI width x height. [int]",
                                                            "type": "integer"
                                                          },
                                                          "enlarge": {
                                                            "description": "Enlarge output if the original is smaller than the requested size [bool]",
                                                            "type": "boolean"
                                                          },
                                                          "format": {
                                                            "description": "Output format of the thumbnail. [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png",
                                                              "webp"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "jpegquality": {
                                                            "description": "JPEG quality: 1 (worst) to 100 (best). Use 0 to not explicitely set quality. [int]",
                                                            "type": "integer"
                                                          },
                                                          "resize_mode": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "height",
                                                              "max",
                                                              "min",
                                                              "width"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "Set the output size. Use 0 to keep the original size. [int]",
                                                            "type": "integer"
                                                          },
                                                          "size_minimum": {
                                                            "description": "Only produce version if source size (largest dimension, either `width` or `height`) is greater or equal `size_minimum`. [int]",
                                                            "type": "integer"
                                                          },
                                                          "strip": {
                                                            "description": "Strip metadata from thumbnail. [bool]",
                                                            "type": "boolean"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"imageconverter:browserthumbs\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  }
                                                ]
                                              },
                                              "type": "array"
                                            },
                                            "watermark": {
                                              "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                              "type": "boolean"
                                            }
                                          },
                                          "type": "object"
                                        },
                                        "office": {
                                          "properties": {
                                            "name": {
                                              "description": "Read-only value with the name of the class.",
                                              "type": "string"
                                            },
                                            "rightsmanagement": {
                                              "description": "If set, this version will be configurable in the rights management of fylr.",
                                              "type": "boolean"
                                            },
                                            "sourceversion": {
                                              "description": "The version which is used to produce this version.",
                                              "type": "string"
                                            },
                                            "standard": {
                                              "description": "If set, this version will be included in the standard info.",
                                              "type": "boolean"
                                            },
                                            "uploadenabledextensions": {
                                              "items": {
                                                "description": "Extensions which are allowed in this class for upload.",
                                                "enum": [
                                                  "csv",
                                                  "doc",
                                                  "docx",
                                                  "epub",
                                                  "indd",
                                                  "odp",
                                                  "ods",
                                                  "odt",
                                                  "otf",
                                                  "pdf",
                                                  "ppsx",
                                                  "ppt",
                                                  "pptx",
                                                  "rtf",
                                                  "ttf",
                                                  "txt",
                                                  "xls",
                                                  "xlsx"
                                                ],
                                                "type": "string"
                                              },
                                              "type": "array"
                                            },
                                            "uploadmaxfilesize": {
                                              "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                              "type": "string"
                                            },
                                            "versions": {
                                              "items": {
                                                "oneOf": [
                                                  {
                                                    "description": "Recipe \"pdfconverter:pdfpages\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "csv",
                                                                "doc",
                                                                "docx",
                                                                "epub",
                                                                "indd",
                                                                "odp",
                                                                "ods",
                                                                "odt",
                                                                "pdf",
                                                                "ppsx",
                                                                "ppt",
                                                                "pptx",
                                                                "rtf",
                                                                "txt",
                                                                "xls",
                                                                "xlsx"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "csv",
                                                            "doc",
                                                            "docx",
                                                            "epub",
                                                            "indd",
                                                            "odp",
                                                            "ods",
                                                            "odt",
                                                            "pdf",
                                                            "ppsx",
                                                            "ppt",
                                                            "pptx",
                                                            "rtf",
                                                            "txt",
                                                            "xls",
                                                            "xlsx"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "min_size": {
                                                            "description": "Size in pixels of the shortest side of the page.\n [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"pdfconverter:pdfpages\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"officeconverter:pdf\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "csv",
                                                                "doc",
                                                                "docx",
                                                                "epub",
                                                                "odp",
                                                                "ods",
                                                                "odt",
                                                                "ppsx",
                                                                "ppt",
                                                                "pptx",
                                                                "rtf",
                                                                "txt",
                                                                "xls",
                                                                "xlsx"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "csv",
                                                            "doc",
                                                            "docx",
                                                            "epub",
                                                            "odp",
                                                            "ods",
                                                            "odt",
                                                            "ppsx",
                                                            "ppt",
                                                            "pptx",
                                                            "rtf",
                                                            "txt",
                                                            "xls",
                                                            "xlsx"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {},
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"officeconverter:pdf\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"officeconverter:preview\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "csv",
                                                                "doc",
                                                                "docx",
                                                                "epub",
                                                                "odp",
                                                                "ods",
                                                                "odt",
                                                                "ppsx",
                                                                "ppt",
                                                                "pptx",
                                                                "rtf",
                                                                "txt",
                                                                "xls",
                                                                "xlsx"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "csv",
                                                            "doc",
                                                            "docx",
                                                            "epub",
                                                            "odp",
                                                            "ods",
                                                            "odt",
                                                            "ppsx",
                                                            "ppt",
                                                            "pptx",
                                                            "rtf",
                                                            "txt",
                                                            "xls",
                                                            "xlsx"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format of the thumbnail [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png",
                                                              "webp"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "resize_mode": {
                                                            "description": " [select]",
                                                            "enum": [
                                                              "",
                                                              "height",
                                                              "max",
                                                              "min",
                                                              "width"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the output size. [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"officeconverter:preview\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"officeconverter:browserthumbs\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "indd",
                                                                "pdf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "indd",
                                                            "pdf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "output format of the thumbnail [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png",
                                                              "webp"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the output size. [int]",
                                                            "type": "integer"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"officeconverter:browserthumbs\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"officeconverter:font\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "otf",
                                                                "ttf"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "otf",
                                                            "ttf"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "size": {
                                                            "description": "set the output size. This will produce a squared preview [int]",
                                                            "type": "integer"
                                                          },
                                                          "text": {
                                                            "description": "text to render on the preview [string]",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"officeconverter:font\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  }
                                                ]
                                              },
                                              "type": "array"
                                            },
                                            "watermark": {
                                              "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                              "type": "boolean"
                                            }
                                          },
                                          "type": "object"
                                        },
                                        "video": {
                                          "properties": {
                                            "name": {
                                              "description": "Read-only value with the name of the class.",
                                              "type": "string"
                                            },
                                            "rightsmanagement": {
                                              "description": "If set, this version will be configurable in the rights management of fylr.",
                                              "type": "boolean"
                                            },
                                            "sourceversion": {
                                              "description": "The version which is used to produce this version.",
                                              "type": "string"
                                            },
                                            "standard": {
                                              "description": "If set, this version will be included in the standard info.",
                                              "type": "boolean"
                                            },
                                            "uploadenabledextensions": {
                                              "items": {
                                                "description": "Extensions which are allowed in this class for upload.",
                                                "enum": [
                                                  "3gp",
                                                  "asf",
                                                  "avi",
                                                  "flv",
                                                  "hevc",
                                                  "m2v",
                                                  "m4v",
                                                  "mjpeg",
                                                  "mkv",
                                                  "mov",
                                                  "mp4",
                                                  "mpeg",
                                                  "mpg",
                                                  "mts",
                                                  "mxf",
                                                  "ogv",
                                                  "rm",
                                                  "swf",
                                                  "ts",
                                                  "vob",
                                                  "webm",
                                                  "wmv",
                                                  "wtv"
                                                ],
                                                "type": "string"
                                              },
                                              "type": "array"
                                            },
                                            "uploadmaxfilesize": {
                                              "description": "The upload maximum file size for this class, given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                              "type": "string"
                                            },
                                            "versions": {
                                              "items": {
                                                "oneOf": [
                                                  {
                                                    "description": "Recipe \"videoconverter:resize\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "3gp",
                                                                "asf",
                                                                "avi",
                                                                "flv",
                                                                "hevc",
                                                                "m2v",
                                                                "m4v",
                                                                "mjpeg",
                                                                "mkv",
                                                                "mov",
                                                                "mp4",
                                                                "mpeg",
                                                                "mpg",
                                                                "mts",
                                                                "mxf",
                                                                "ogv",
                                                                "rm",
                                                                "swf",
                                                                "ts",
                                                                "vob",
                                                                "webm",
                                                                "wmv",
                                                                "wtv"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "3gp",
                                                            "asf",
                                                            "avi",
                                                            "flv",
                                                            "hevc",
                                                            "m2v",
                                                            "m4v",
                                                            "mjpeg",
                                                            "mkv",
                                                            "mov",
                                                            "mp4",
                                                            "mpeg",
                                                            "mpg",
                                                            "mts",
                                                            "mxf",
                                                            "ogv",
                                                            "rm",
                                                            "swf",
                                                            "ts",
                                                            "vob",
                                                            "webm",
                                                            "wmv",
                                                            "wtv"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "ffmpeg_params": {
                                                            "description": "Additional ffmpeg options for the video production, default is: -codec:v libx264 -profile:v high -level 4.1 -preset fast -crf 20 -pix_fmt yuv420p -codec:a aac -b:a 128k -ac 2 -movflags +faststart [string]",
                                                            "type": "string"
                                                          },
                                                          "height": {
                                                            "description": "set the output height [int]",
                                                            "type": "integer"
                                                          },
                                                          "height_minimum": {
                                                            "description": "only produce version if source height is greater or equal height_minimum [int]",
                                                            "type": "integer"
                                                          },
                                                          "timeout": {
                                                            "description": "maximum duration to encode the video, e.g. \"1m\" or \"1h\" [string]",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"videoconverter:resize\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  },
                                                  {
                                                    "description": "Recipe \"videoconverter:thumbnail\"",
                                                    "properties": {
                                                      "custommetadata": {
                                                        "properties": {
                                                          "extensions": {
                                                            "description": "If given, only run the custom metadata if the extension of the version matches.",
                                                            "items": {
                                                              "enum": [
                                                                "3gp",
                                                                "asf",
                                                                "avi",
                                                                "flv",
                                                                "hevc",
                                                                "m2v",
                                                                "m4v",
                                                                "mjpeg",
                                                                "mkv",
                                                                "mov",
                                                                "mp4",
                                                                "mpeg",
                                                                "mpg",
                                                                "mts",
                                                                "mxf",
                                                                "ogv",
                                                                "rm",
                                                                "swf",
                                                                "ts",
                                                                "vob",
                                                                "webm",
                                                                "wmv",
                                                                "wtv"
                                                              ],
                                                              "type": "string"
                                                            },
                                                            "type": "array"
                                                          },
                                                          "recipename": {
                                                            "description": "Recipe to process the custom metadata.",
                                                            "enum": [
                                                              "_metadata:ocr"
                                                            ],
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "displayname": {
                                                        "type": "object",
                                                        "properties": {
                                                          "de-DE": {
                                                            "type": "string"
                                                          },
                                                          "en-US": {
                                                            "type": "string"
                                                          }
                                                        },
                                                        "example": {
                                                          "de-DE": "Deutscher text",
                                                          "en-US": "English text"
                                                        }
                                                      },
                                                      "extensions": {
                                                        "items": {
                                                          "enum": [
                                                            "3gp",
                                                            "asf",
                                                            "avi",
                                                            "flv",
                                                            "hevc",
                                                            "m2v",
                                                            "m4v",
                                                            "mjpeg",
                                                            "mkv",
                                                            "mov",
                                                            "mp4",
                                                            "mpeg",
                                                            "mpg",
                                                            "mts",
                                                            "mxf",
                                                            "ogv",
                                                            "rm",
                                                            "swf",
                                                            "ts",
                                                            "vob",
                                                            "webm",
                                                            "wmv",
                                                            "wtv"
                                                          ],
                                                          "type": "string"
                                                        },
                                                        "type": "array"
                                                      },
                                                      "group": {
                                                        "type": "string"
                                                      },
                                                      "name": {
                                                        "type": "string"
                                                      },
                                                      "params": {
                                                        "properties": {
                                                          "format": {
                                                            "description": "set the format of the target. [select]",
                                                            "enum": [
                                                              "jpg",
                                                              "png"
                                                            ],
                                                            "type": "string"
                                                          },
                                                          "size": {
                                                            "description": "set the target size (eg 128) [string]",
                                                            "type": "string"
                                                          },
                                                          "timeout": {
                                                            "description": "maximum duration to produce the thumbnail, e.g. \"1m\" or \"1h\" [string]",
                                                            "type": "string"
                                                          },
                                                          "video-thumb-select": {
                                                            "description": "\"hh:mm:ss.sss\", \"ss.sss\", \"auto\" or \"no-ffmpegthumbnailer\".\n [string]",
                                                            "type": "string"
                                                          }
                                                        },
                                                        "type": "object"
                                                      },
                                                      "recipename": {
                                                        "description": "This oneOf block is for \"videoconverter:thumbnail\"",
                                                        "type": "string"
                                                      }
                                                    },
                                                    "type": "object"
                                                  }
                                                ]
                                              },
                                              "type": "array"
                                            },
                                            "watermark": {
                                              "description": "If set, frontends can use this information to prefer to display a non-watermark version over one with a watermark.",
                                              "type": "boolean"
                                            }
                                          },
                                          "type": "object"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "custommetadata": {
                                      "properties": {
                                        "extensions": {
                                          "description": "If given, only run the custom metadata if the extension of the original or version matches.",
                                          "items": {
                                            "enum": [
                                              "3gp",
                                              "aac",
                                              "ai",
                                              "aiff",
                                              "arw",
                                              "asf",
                                              "avi",
                                              "avif",
                                              "bmp",
                                              "cr2",
                                              "cr3",
                                              "crw",
                                              "csv",
                                              "dng",
                                              "doc",
                                              "docx",
                                              "dts",
                                              "eps",
                                              "epub",
                                              "flac",
                                              "flv",
                                              "gif",
                                              "heic",
                                              "hevc",
                                              "ico",
                                              "indd",
                                              "jfif",
                                              "jp2",
                                              "jpeg",
                                              "jpg",
                                              "m2v",
                                              "m4a",
                                              "m4v",
                                              "mjpeg",
                                              "mkv",
                                              "mov",
                                              "mp2",
                                              "mp3",
                                              "mp4",
                                              "mpeg",
                                              "mpg",
                                              "mts",
                                              "mxf",
                                              "nef",
                                              "odp",
                                              "ods",
                                              "odt",
                                              "oga",
                                              "ogg",
                                              "ogv",
                                              "opus",
                                              "otf",
                                              "pcd",
                                              "pdf",
                                              "png",
                                              "ppm",
                                              "ppsx",
                                              "ppt",
                                              "pptx",
                                              "psd",
                                              "ra",
                                              "raf",
                                              "rm",
                                              "rtf",
                                              "rw2",
                                              "svg",
                                              "swf",
                                              "tif",
                                              "tiff",
                                              "ts",
                                              "ttf",
                                              "txt",
                                              "vob",
                                              "wav",
                                              "webm",
                                              "webp",
                                              "wma",
                                              "wmf",
                                              "wmv",
                                              "wtv",
                                              "xls",
                                              "xlsx"
                                            ],
                                            "type": "string"
                                          },
                                          "type": "array"
                                        },
                                        "includeversions": {
                                          "description": "If set, the custom metadata is produces not only for originals but also for all versions.",
                                          "type": "boolean"
                                        },
                                        "recipename": {
                                          "description": "Recipe to process the custom metadata.",
                                          "enum": [
                                            "_metadata:ocr"
                                          ],
                                          "type": "string"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "uploadallowunknown": {
                                      "description": "If set, the upload of file types which are not enabled in any \"uploadenabledextensions\", is allowed.",
                                      "type": "boolean"
                                    },
                                    "uploadmaxfilesize": {
                                      "description": "The upload maximum file size (can be overwritten by each class), given in a format string which ends in \"b\", \"k\", \"m\", \"g\".",
                                      "type": "string"
                                    }
                                  },
                                  "type": "object",
                                  "x-type": "json"
                                }
                              },
                              "type": "object"
                            },
                            "publish": {
                              "properties": {
                                "collectors": {
                                  "items": {
                                    "properties": {
                                      "display_format": {
                                        "enum": [
                                          "name",
                                          "name_type",
                                          "name_type_doi",
                                          "type"
                                        ],
                                        "type": "string"
                                      },
                                      "displayname": {
                                        "properties": {
                                          "de-DE": {
                                            "type": "string"
                                          },
                                          "en-US": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "internalname": {
                                        "type": "string"
                                      },
                                      "logo": {
                                        "properties": {
                                          "_id": {
                                            "description": "The EAS-ID of the file.",
                                            "type": "integer"
                                          },
                                          "frontend_prefs": {
                                            "additionalProperties": {
                                              "description": "Any value is allowed"
                                            },
                                            "description": "An arbitrary object which is stored alongside with the relation. Make sure your application uses its own top level key in that object and that you do not overwrite existing data (other top level keys).",
                                            "type": "object"
                                          }
                                        },
                                        "type": "object",
                                        "x-type": "file"
                                      },
                                      "prefix": {
                                        "type": "string"
                                      },
                                      "type": {
                                        "type": "string"
                                      },
                                      "url": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "purge": {
                              "properties": {
                                "allow_purge": {
                                  "type": "boolean"
                                },
                                "purge_storage": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "readonly": {
                              "properties": {
                                "enabled": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            },
                            "register": {
                              "properties": {
                                "enable": {
                                  "type": "boolean"
                                },
                                "form": {
                                  "properties": {
                                    "address": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "company": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "department": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "displayname": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "first_name": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "last_name": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "phone": {
                                      "enum": [
                                        "hide",
                                        "require",
                                        "show"
                                      ],
                                      "type": "string"
                                    },
                                    "use_in_user_manager": {
                                      "type": "boolean"
                                    }
                                  },
                                  "type": "object"
                                },
                                "groups": {
                                  "items": {
                                    "properties": {
                                      "group": {
                                        "type": "integer"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "info": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "saml": {
                              "properties": {
                                "cert": {
                                  "type": "string"
                                },
                                "debug": {
                                  "type": "boolean"
                                },
                                "entry_js": {
                                  "type": "string"
                                },
                                "groupmapping": {
                                  "items": {
                                    "properties": {
                                      "group": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "idp_entity_id": {
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "ldap": {
                                  "properties": {
                                    "bindpassword": {
                                      "description": "The string will be encrypted in the server if fylr.encryptionKey is set in fylr.yml. In API responses, if a value is set, the response will always be *** or ***** to indicate that an encrypted value is stored. ***** mean that the value is actually stored encrypted, whereas *** means the value is stored as plain text.",
                                      "type": "string"
                                    },
                                    "bindusername": {
                                      "type": "string"
                                    },
                                    "connections": {
                                      "items": {
                                        "properties": {
                                          "tls_ca_cert": {
                                            "type": "string"
                                          },
                                          "tls_insecure": {
                                            "type": "boolean"
                                          },
                                          "tls_start": {
                                            "type": "boolean"
                                          },
                                          "url": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "type": "array"
                                    },
                                    "groupbasedn": {
                                      "type": "string"
                                    },
                                    "groupfilter": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "loginlink": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "loginlink_internal": {
                                  "properties": {
                                    "de-DE": {
                                      "type": "string"
                                    },
                                    "en-US": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "loginpreferred": {
                                  "type": "boolean"
                                },
                                "loginredirect": {
                                  "type": "boolean"
                                },
                                "signrequest": {
                                  "enum": [
                                    "",
                                    "sha1",
                                    "sha256",
                                    "sha512"
                                  ],
                                  "type": "string"
                                },
                                "sp_entity_id": {
                                  "type": "string"
                                },
                                "url": {
                                  "type": "string"
                                },
                                "usermapping": {
                                  "items": {
                                    "properties": {
                                      "key": {
                                        "enum": [
                                          "address_supplement",
                                          "company",
                                          "country",
                                          "department",
                                          "displayname",
                                          "email",
                                          "first_name",
                                          "house_number",
                                          "last_name",
                                          "login",
                                          "phone",
                                          "postal_code",
                                          "reference",
                                          "state",
                                          "street",
                                          "town"
                                        ],
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "userupdatecolumn": {
                                  "enum": [
                                    "email",
                                    "login",
                                    "reference"
                                  ],
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "transition_webhook": {
                              "properties": {
                                "webhooks": {
                                  "items": {
                                    "properties": {
                                      "include_access_token": {
                                        "type": "boolean"
                                      },
                                      "name": {
                                        "type": "string"
                                      },
                                      "secret": {
                                        "type": "string"
                                      },
                                      "send_authorization_header": {
                                        "type": "boolean"
                                      },
                                      "timeout": {
                                        "type": "integer"
                                      },
                                      "url": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "two_factor": {
                              "properties": {
                                "allow_password_grant": {
                                  "type": "boolean"
                                },
                                "enabled": {
                                  "type": "boolean"
                                },
                                "methods": {
                                  "items": {
                                    "enum": [
                                      "email",
                                      "passkey",
                                      "totp"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "user": {
                              "properties": {
                                "copy_to_event": {
                                  "items": {
                                    "enum": [
                                      "address_supplement",
                                      "company",
                                      "country",
                                      "department",
                                      "first_name",
                                      "house_number",
                                      "last_name",
                                      "login",
                                      "phone",
                                      "postal_code",
                                      "reference",
                                      "state",
                                      "street",
                                      "town"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "default_delete_policy": {
                                  "enum": [
                                    "archive",
                                    "ask",
                                    "delete"
                                  ],
                                  "type": "string"
                                },
                                "user_in_event_group": {
                                  "items": {
                                    "enum": [
                                      "ADMIN",
                                      "DOWNLOAD",
                                      "EXPORT",
                                      "FRONTEND",
                                      "LOGIN_LOGOUT",
                                      "SYSTEM",
                                      "TASK",
                                      "UPLOAD"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "webdav": {
                              "properties": {
                                "hotfolder": {
                                  "type": "boolean"
                                },
                                "hotfolder_wait_sec": {
                                  "type": "integer"
                                },
                                "read_write_access": {
                                  "type": "boolean"
                                }
                              },
                              "type": "object"
                            }
                          },
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            }
          },
          "202": {
            "description": "The save needs confirmation before it can complete. Two cases:\n(1) the config has errors that are individually savable (for example\nan LDAP connection that fails to dial) — resend with\n`save=ignore_errors` (button `name`=`save`, `value`=`ignore_errors`);\n(2) the frontend or database languages changed — resend with\n`reindex=skip|reindex|reindex_block` and `confirm=yes`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigPost202"
                }
              }
            }
          },
          "400": {
            "description": "The config payload could not be processed. A malformed, empty or\n(for `DELETE`) non-empty request body, or a body whose top-level\nvalues are not maps, is rejected as `code` `ServerGeneric`. A payload\nthat parses but fails base-config validation carries a `BaseConfig*`\n`code`: a parse failure is `BaseConfigParse`; a value that does not\nmatch the expected type, or a rejection from a base-config consumer\n(license, LDAP, mail address, ...), raises its own code\n(`BaseConfigInvalidLicense`, `BaseConfigLDAPDial`,\n`BaseConfigInvalidMailAddress`, ...). The `error` field carries the\nhuman-readable message; branch on `code`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.config` system right required\nto write the base configuration (`system.root` always satisfies it).\n`code` is `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/config/{path}": {
      "x-path": "config",
      "description": "Read or patch a **single** base-config item — or a nested value within one —\naddressed by its path. The path selects the item under either\n`system/config/\u003cname\u003e/...` or `plugin/\u003cplugin\u003e/config/\u003cname\u003e/...`. These\noperations are the per-item counterpart to the whole-config `GET`/`POST` on\n`/config`.\n",
      "parameters": [
        {
          "name": "path",
          "in": "path",
          "required": true,
          "description": "Slash-separated config path, either `system/config/\u003cname\u003e/...` or\n`plugin/\u003cplugin\u003e/config/\u003cname\u003e/...`. The leading segments select the\nconfig item; any further segments address a nested value inside it. A\nsegment may itself contain a `/` encoded as `%2F`. Examples:\n`system/config/name`, `system/config/name/title/de-DE`,\n`plugin/fylr_example/config/custom/data`.\n",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Read a single base-config item or nested value",
        "tags": [
          "config"
        ],
        "description": "Returns the config sub-tree addressed by the path — a config item object,\nor a scalar when the path reaches a leaf value. Like `GET /config`, any\nauthenticated user may read; items the session is not permitted to read\nare filtered out. The request is never rejected for lack of\n`system.config`.\n\nDiffers from easydb 5: reading the config does not require the\n`system.config` system right (in easydb 5 the `GET` config call requires\n`system.config`).\n",
        "responses": {
          "200": {
            "description": "The config sub-tree (an object) or the scalar value addressed by the\npath.\n",
            "content": {
              "application/json": {
                "schema": {
                  "description": "The config item object, or the scalar value at the addressed\nleaf.\n",
                  "example": {
                    "title": {
                      "de-DE": "FYLR apitest [DE]",
                      "en-US": "FYLR apitest [EN]"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed config path is unknown — no such system/plugin config\nname, or the path resolves to no value. `code` is\n`BaseConfigPathNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Set a single base-config item or nested value",
        "tags": [
          "config"
        ],
        "description": "Sets the JSON value sent in the body at the addressed path, using an\n`sjson` patch on the current stored value, then re-validates and re-saves\nthe whole affected config item. Because the whole item is re-saved, this\ncan raise the same `400` / `202` flows as `POST /config`. An empty body is\nrejected. Requires `system.config` (`system.root` always satisfies it).\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "description": "The JSON value to set at the path. May be an object, array or\nscalar. Must not be empty.\n",
                "example": {
                  "a": "b"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The patched config sub-tree (the value now stored at the path).\n",
            "content": {
              "application/json": {
                "schema": {
                  "description": "The value stored at the addressed path after the patch.",
                  "example": {
                    "a": "b"
                  }
                }
              }
            }
          },
          "202": {
            "description": "The patch needs confirmation before it can complete — same cases as\n`POST /config` (savable config errors → resend with\n`save=ignore_errors`; language change → resend with\n`reindex=...` and `confirm=yes`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigPost202"
                }
              }
            }
          },
          "400": {
            "description": "The config payload could not be processed. A malformed, empty or\n(for `DELETE`) non-empty request body, or a body whose top-level\nvalues are not maps, is rejected as `code` `ServerGeneric`. A payload\nthat parses but fails base-config validation carries a `BaseConfig*`\n`code`: a parse failure is `BaseConfigParse`; a value that does not\nmatch the expected type, or a rejection from a base-config consumer\n(license, LDAP, mail address, ...), raises its own code\n(`BaseConfigInvalidLicense`, `BaseConfigLDAPDial`,\n`BaseConfigInvalidMailAddress`, ...). The `error` field carries the\nhuman-readable message; branch on `code`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.config` system right required\nto write the base configuration (`system.root` always satisfies it).\n`code` is `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed config path is unknown — no such system/plugin config\nname, or the path resolves to no value. `code` is\n`BaseConfigPathNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Remove a single base-config item or nested value",
        "tags": [
          "config"
        ],
        "description": "Removes the value at the addressed path (an `sjson` delete on the current\nstored value), then re-saves the affected config item through the same\npath as `POST /config`, so it can raise the same `400` / `202` flows.\nSending a request body is rejected (`400`, `code` `ServerGeneric`). A\n`DELETE` on bare `/config` (no sub-path) always returns `404`. Requires\n`system.config` (`system.root` always satisfies it).\n",
        "responses": {
          "200": {
            "description": "The value at the path was removed. The body is the value at the path\nafter deletion — `null` for a removed leaf.\n",
            "content": {
              "application/json": {
                "schema": {
                  "description": "The value at the addressed path after deletion.",
                  "example": null
                }
              }
            }
          },
          "202": {
            "description": "The re-save after deletion needs confirmation before it can complete\n— same cases as `POST /config` (savable config errors → resend with\n`save=ignore_errors`; language change → resend with `reindex=...` and\n`confirm=yes`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigPost202"
                }
              }
            }
          },
          "400": {
            "description": "The config payload could not be processed. A malformed, empty or\n(for `DELETE`) non-empty request body, or a body whose top-level\nvalues are not maps, is rejected as `code` `ServerGeneric`. A payload\nthat parses but fails base-config validation carries a `BaseConfig*`\n`code`: a parse failure is `BaseConfigParse`; a value that does not\nmatch the expected type, or a rejection from a base-config consumer\n(license, LDAP, mail address, ...), raises its own code\n(`BaseConfigInvalidLicense`, `BaseConfigLDAPDial`,\n`BaseConfigInvalidMailAddress`, ...). The `error` field carries the\nhuman-readable message; branch on `code`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.config` system right required\nto write the base configuration (`system.root` always satisfies it).\n`code` is `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed config path is unknown — no such system/plugin config\nname, or the path resolves to no value. `code` is\n`BaseConfigPathNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/db_info/create": {
      "x-path": "/db_info",
      "description": "Read-only permission probe for object creation. For a given `objecttype`,\n`pool_id` and `tag_ids` combination it reports where the requesting user may\ncreate objects, returning `_available_objecttypes`, `_available_masks` and\n`_available_tags`. No object is created.\n",
      "post": {
        "description": "Retrieve information about if objects can be created in a specific object\ntype and pool configuration. Tags can also be provided to perform the check.\n\n* With no further parameters, object types are returned where the user can create new objects:\n  for a pooled objecttype this checks each pool for the `create` right; a non-pool objecttype\n  is listed if it grants the `create` right directly.\n* With `objecttype` set, a list of `pool_ids` is returned alongside the object type.\n* With `tag_ids` unsent the server uses the default tag set for the objecttype/pool combination to check the rights.\n* With `tag_ids` provided, these ids are used to check the rights.\n* With `tag_ids` set to `null`, the rights are checked without tag filters.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "objecttype": {
                    "type": "string",
                    "description": "The object type to check the create permissions for. If omitted, the check will include all object types.\n"
                  },
                  "pool_id": {
                    "type": "integer",
                    "description": "The ID of the pool to check the permissions for.\n"
                  },
                  "tag_ids": {
                    "type": "array",
                    "nullable": true,
                    "items": {
                      "type": "integer"
                    },
                    "description": "List of tag IDs which are assumed for the new object. If\nomitted, the check will include the default tags. If set to\n`null`, the tags check will be omitted. This can be useful if\nonly a certain combination (which is not the default\ncombination) of tags enables permissions for the user. An id\nthat matches no tag returns code `TagNotFound`; an id that\nexists but is not enabled for the objecttype/pool returns code\n`TagNotEnabled`. These two codes are raised only by\n`db_info/create`.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "An object describing the possibilites to create an object for the user.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_available_objecttypes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "integer",
                            "description": "The ID of the object type.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "The name of the object type.\n"
                          },
                          "pool_ids": {
                            "type": "array",
                            "items": {
                              "type": "integer"
                            },
                            "description": "List of pool IDs in which the user holds the `create` right for the specific object type.\n"
                          }
                        }
                      }
                    },
                    "_available_masks": {
                      "description": "List of masks the user may create objects against for the\nrequested object type and pool. The list is ordered by\npreference (as defined for the object type or pool). If no\norder is defined, the standard mask from the data model is\nthe preferred one. If the object type or pool defines a mask\nto not render, it is omitted from this list. This list is\nonly populated when a single `objecttype` (and, for pooled\nobject types, a `pool_id`) is requested.\n",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "integer",
                            "description": "Mask ID, the `_all_fields` mask will have no `_id`.\nOnly `system.root` will have access to the\n`_all_fields` mask.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name of the mask.\n"
                          }
                        }
                      }
                    },
                    "_available_tags": {
                      "description": "List of available tags for the object type and pool requested.\nObject types and pools can enable and disable tags, so not all\ntags of the system may be available.\n",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "integer",
                            "description": "ID of the tag.\n"
                          },
                          "is_default": {
                            "type": "boolean",
                            "description": "Flag indicating that the tag is a default tag.\n\nDiffers from easydb 5: the field is named `is_default`\n(no leading underscore); easydb 5 documents it as\n`_is_default`.\n"
                          }
                        }
                      }
                    }
                  },
                  "example": {
                    "_available_objecttypes": [
                      {
                        "_id": 27,
                        "name": "nested",
                        "pool_ids": [
                          1,
                          2,
                          3,
                          4
                        ]
                      }
                    ],
                    "_available_masks": [
                      {
                        "_id": 11,
                        "name": "nested__all_fields"
                      }
                    ],
                    "_available_tags": [
                      {
                        "_id": 1,
                        "is_default": true
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "The permission check could not be performed. When present, the `code`\nfield of the response identifies the specific reason; not every 400\ncarries a stable `code` (input-validation failures are returned as\ngeneric messages).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/NoMasksForCreateError"
                    },
                    {
                      "$ref": "#/components/schemas/ObjecttypeNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/TagNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/TagNotEnabledError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n\nDiffers from easydb 5: a missing/invalid session is reported as `401`\n(code `UserRequired`); easydb 5 documents the unauthenticated case as a\n`400`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/db_info/update": {
      "x-path": "/db_info",
      "description": "Read-only permission probe for object updates. Given an `objecttype` and\n`object_ids` (optionally an assumed `pool_id` or `tag_ids`), it computes the\nrights the session would hold as if the object(s) had been moved or retagged,\nreturning `_available_masks`, `_available_tags`, `_available_pools` and the\ncompiled `_generated_rights`. No object is modified.\n",
      "post": {
        "description": "Retrieve information about how objects can be updated using a new pool or tags.\n* An `objecttype` and `object_ids` must be provided. If either is missing,\n  the request fails with a generic `400`.\n* If a pool change is planned, the `pool_id` as the new pool ID can be sent. All\n  permission compilations are done with the new pool ID, except for the `unlink`\n  permission which is checked against the current pool ID of the object(s).\n* Masks, tags and pools are listed only if they apply to all object(s).\n\nThis is a read-only permission probe. Passing `pool_id` or `tag_ids`\ncomputes the rights as if the object(s) had been moved or retagged, but\nno object is actually modified.\n\nDiffers from easydb 5: `_available_masks` and `_available_tags` are\npopulated only when the session holds the `read` right on every probed\nobject; easydb 5 documents these two lists as \"only provided if 'write'\nis in `_generated_rights`\".\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "objecttype",
                  "object_ids"
                ],
                "properties": {
                  "objecttype": {
                    "type": "string",
                    "description": "The object type to check the update permissions for.\n"
                  },
                  "object_ids": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "The object IDs to check permissions for.\n"
                  },
                  "pool_id": {
                    "type": "integer",
                    "description": "The ID of the pool to check the permissions for. This assumes that the object(s) will be moved to that pool.\n"
                  },
                  "tag_ids": {
                    "type": "array",
                    "nullable": true,
                    "items": {
                      "type": "integer"
                    },
                    "description": "List of tag IDs which are assumed for the updated object. If\nomitted, the check will use the current tags of the object(s).\nSetting `null` is the same as setting `[]`. This assumes that\nthe update will remove all tags from the object(s).\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A list of masks, pool IDs, tags and _generated_rights compiled for all\nobjects together. The lists contain only items which are available for\nall objects.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_available_masks": {
                      "description": "List of masks available for the object(s) after the assumed\nupdate. The list is ordered by preference (as defined for the\nobject type or pool). If no order is defined, the standard mask\nfrom the data model is the preferred one. If the object type or\npool defines a mask to not render, it is omitted from this list.\nOnly populated when the requesting session holds `read` on every\nobject.\n",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "integer",
                            "description": "Mask ID, the `_all_fields` mask will have no `_id`.\nOnly `system.root` will have access to the\n`_all_fields` mask.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name of the mask.\n"
                          }
                        }
                      }
                    },
                    "_available_tags": {
                      "description": "List of available tags for the object type and pool\nrequested. Object types and pools can enable and disable\ntags, so not all tags of the system may be available.\nOnly populated when the requesting session holds `read` on\nevery object. Unlike `db_info/create`, the items carry no\n`is_default` flag.\n",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_id": {
                            "type": "integer",
                            "description": "ID of the tag.\n"
                          }
                        }
                      }
                    },
                    "_available_pools": {
                      "description": "List of pool IDs the object(s) can be in. The current pool of\nthe object(s) is always included (when shared by all object(s)).\nA different destination pool is listed only if the user holds\nthe `unlink` right in the current pool and the `link` right in\nthat destination pool. `system.root` sees all pools. Only\npopulated when the requesting session holds `read` on every\nobject.\n",
                      "type": "array",
                      "items": {
                        "type": "integer"
                      }
                    },
                    "_generated_rights": {
                      "description": "The compiled, effective permissions the requesting session would\nhold on the object(s) after the assumed update (pool / tag change).\n\nA right is listed **only if it holds identically for every probed\nobject** — if even one object lacks it, the key is omitted. Keys\nare a subset of the rights catalog (`GET /api/v1/right`); for this\nendpoint the possible keys are `read`, `write`, `delete`, `acl`,\n`change_owner`, `unlink` and `owner`. `unlink` is evaluated against\neach object's **current** pool, the rest against the updated\n(moved / retagged) object.\n\nEach value is a per-right configuration object (`RightItemApi`).\nIn this endpoint the value is always an **empty object** `{}`\n(membership of the key is the only signal — fylr does not scope the\nprobe result further), but the type matches the richer\n`_generated_rights` returned by the object / pool / group / user\nendpoints, where the per-right object can carry mask, objecttype,\npool, file-class and grantable constraints.\n",
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/GeneratedRightsApi"
                        }
                      ]
                    }
                  },
                  "example": {
                    "_available_masks": [
                      {
                        "_id": 11,
                        "name": "nested__all_fields"
                      },
                      {
                        "_id": 12,
                        "name": "mask_with_splitters"
                      },
                      {
                        "name": "_all_fields"
                      }
                    ],
                    "_available_tags": [
                      {
                        "_id": 2
                      },
                      {
                        "_id": 3
                      },
                      {
                        "_id": 1
                      }
                    ],
                    "_available_pools": [
                      1,
                      2,
                      3,
                      4,
                      5
                    ],
                    "_generated_rights": {
                      "read": {},
                      "write": {},
                      "delete": {},
                      "acl": {},
                      "change_owner": {},
                      "unlink": {},
                      "owner": {}
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The permission check could not be performed. When present, the `code`\nfield of the response identifies the specific reason; not every 400\ncarries a stable `code` (input-validation failures are returned as\ngeneric messages).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/NoMasksForCreateError"
                    },
                    {
                      "$ref": "#/components/schemas/ObjecttypeNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/TagNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/TagNotEnabledError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n\nDiffers from easydb 5: a missing/invalid session is reported as `401`\n(code `UserRequired`); easydb 5 documents the unauthenticated case as a\n`400`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/db/{objecttype}": {
      "x-path": "/db",
      "description": "The `/db` endpoint is **datamodel-driven**. `{objecttype}` is the name of an\nobject type defined in this instance's datamodel. For every object type,\n**fylr** exposes the same set of operations:\n\n  * `POST /db/{objecttype}` — create or update objects.\n  * `GET /db/{objecttype}/{mask}/{objectId}` — read a single object.\n  * `GET /db/{objecttype}/{mask}/list` — list objects.\n  * `DELETE /db/{objecttype}` — delete objects.\n\nEvery object is shaped by a *mask* of its object type. The mask selects\nwhich fields are present and whether each one is writable or read-only.\n\nThese operations are documented generically here. When the instance has\nobject types defined, the sections below additionally describe each object\ntype concretely, with its real masks and field schemas. If only this\ngeneric overview is shown, no object types have been defined yet.\n",
      "post": {
        "summary": "Create or update objects of any object type.",
        "description": "Create or update objects. Replace `{objecttype}` in the URL with the name\nof an object type from this instance's datamodel.\n\nThe request body is an array, so multiple objects can be created or\nupdated in a single call. Each object carries an `_objecttype` matching\nthe URL and a `_mask`. An object is **created** when it has no `_version`\n(or `_version` is `1`) and **updated** otherwise; on update the supplied\n`_version` must match the version currently stored.\n\nOn create, `_id` (unique per object type) and `_system_object_id` (unique\nper instance) are assigned from a server-side counter that is not rolled\nback with the request: ids are never reused, and a save that fails after\nthey are drawn leaves a gap in the numbering. Gaps are expected.\n\nSaving an object requires the `read` permission on a linked object only\nwhen the save introduces that target at a **new location** — a field, or\na nested row (identified by its `_uuid`) and sub-field, where the object's\ncommitted version did not already link it. A target sent back at the same\nlocation is exempt, even if its row moved position or other rows around it\nwere removed. Moving a link to a different field or nested row, or\nreplacing it with a not-previously-linked target there, requires `read` on\nthat target; a caller with `write` on the object but no `read` on it is\nthen rejected with `403 ObjectInsufficientRights` (`right: read`). Being\nlinked elsewhere in the same object is not enough — it must be the same\nlocation. The frontend round-trips the `_uuid` of existing nested rows, so\nordinary edits keep their unchanged links exempt.\n\nDiffers from easydb 5: both create and update use `POST`, and create\nversus update is decided by `_version` (create when absent or `1`), not by\nwhether `_id` is set. easydb 5 distinguishes the two by HTTP method —\n`PUT` to create with no `_id`, `POST` to update with `_id` set.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "format",
            "in": "query",
            "description": "Render format for the objects returned in the response. This only\naffects the representation sent back to the client, not how the\nrequest body is interpreted.\n",
            "schema": {
              "type": "string",
              "default": "standard",
              "enum": [
                "short",
                "standard",
                "standard_extended",
                "long",
                "long_inheritance",
                "full",
                "full_inheritance"
              ]
            }
          },
          {
            "name": "dry_run",
            "in": "query",
            "description": "If set, **fylr** runs the validation of the save — schema and\nconstraint checks together with the permission checks — but stops\nbefore persisting anything and returns the objects it would have\nwritten. Use this to check a payload without changing any data.\n\nBecause nothing is written, **no ids are assigned**: an object that\nwould be created comes back without an `_id` or `_system_object_id`\n(these are drawn only when the object is actually stored). On an\nupdate the existing ids are echoed back unchanged.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "collection",
            "in": "query",
            "description": "ID of a collection. When set, the objects created by this request are\nadditionally linked into the collection with this ID. Must be a\npositive integer.\n",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          },
          {
            "name": "collection_policy",
            "in": "query",
            "description": "Controls what happens to an object's collection memberships when the\nupdate makes it an invalid member of a collection.\n  * `setinvalid`: keep the link but flag it as invalid.\n  * `remove`: remove the object from the affected collections.\n",
            "schema": {
              "type": "string",
              "enum": [
                "setinvalid",
                "remove"
              ]
            }
          },
          {
            "name": "file_url_expire",
            "in": "query",
            "description": "Number of days the signed file URLs contained in the response stay\nvalid. If omitted, the expiry configured for the instance is used.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip_reverse_nested",
            "in": "query",
            "description": "Controls how the save treats **reverse-nested** objects, which are\ngoverned by their top-level object. This is primarily a **save-path**\nswitch, not just a response option.\n\nBy default (flag not set), the reverse-nested objects currently\nattached to the top-level object are reconciled against the payload:\nany that the object still has but that are **omitted** from the\nrequest are **deleted** (with a `\u003creverse nested delete: …\u003e` comment).\nTo keep one you do **not** need to resend it in full — include it with\nits current `_version` unchanged and it is left untouched. Reverse-\nnested reached through a field that is read-only in the `_mask` are\nnever deleted this way.\n\nWhen set, **fylr** skips this reconciliation entirely: no reverse-\nnested object is deleted, and any reverse-nested objects in the payload\nare ignored for saving — the top-level object is saved on its own. The\nflag additionally omits reverse-nested objects from the response.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "skip_bidirectional_update",
            "in": "query",
            "description": "If set, **fylr** does not update the opposite side of bidirectional\nlinks affected by this request. The link is still written on the\nobject being saved.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "skip_index",
            "in": "query",
            "description": "If set, **fylr** does not queue search-index jobs for the saved\nobjects. They are written to the database but do not appear in\n`/api/search` results until indexed by a later operation.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "await_index",
            "in": "query",
            "description": "Maximum number of seconds to wait until the search-index jobs queued\nby this request have been processed and the touched indices have\nbeen refreshed: the saved objects are visible in `/api/search`\nresults when the response arrives. Without this parameter (or with\n`0`) indexing is asynchronous, so a search directly after the save\nmay not find the objects yet.\n\nIf the request's index jobs are not processed within the given\nseconds, the request still succeeds — the objects are saved, they\nare only not searchable yet. The response then carries the\n`X-Fylr-Error` / `X-Fylr-Error-Code` headers describing the\nunfinished wait. Ignored when `skip_index` or `dry_run` is set.\n",
            "schema": {
              "type": "integer",
              "format": "int64",
              "example": 60
            }
          },
          {
            "name": "skip_constraints",
            "in": "query",
            "description": "If set, **fylr** skips constraint checks while saving. This permits\nobjects without a pool, duplicate nested `_uuid` values and multiple\ntags from the same tag group. Intended for migrations and bulk\nimports; use with care.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "skip_plugins",
            "in": "query",
            "description": "If set, **fylr** does not run `db_pre_save` plugin callbacks for this\nrequest. Requires the `system.root` permission.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "skip_events",
            "in": "query",
            "description": "If set, **fylr** does not write entries to the event log for the saved\nobjects. Requires the `system.root` permission.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "confirmTransition",
            "in": "query",
            "description": "Confirmation token for a workflow transition that requires explicit\nconfirmation. When a transition needs confirmation, **fylr** answers\nwith a `202` response describing it; resend the request with this\nparameter set to the value taken from that response.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "revoke",
            "in": "query",
            "description": "Set to `yes` to confirm that the requesting user accepts losing their\nown access to an object as a result of the save, for example after\nchanging its `_acl` or owner. Without this confirmation **fylr**\nanswers with a `202` response instead of saving.\n",
            "schema": {
              "type": "string",
              "enum": [
                "yes"
              ]
            }
          },
          {
            "name": "revoke:confirmTransition",
            "in": "query",
            "description": "Combined confirmation that acknowledges both an ACL revocation and a\nworkflow transition in a single request. The value has the form\n`yes:\u003ctoken\u003e`, where `\u003ctoken\u003e` is the `confirmTransition` value. Use\nthis when one save triggers both confirmations at once.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "reverse_pool_changed_mode",
            "in": "query",
            "description": "Decides what happens to the pool of reverse objects when the pool of\nthe top level object changes.\n  * `reverse_pool_changed_always`: move all reverse objects into the\n    new pool.\n  * `reverse_pool_changed_never`: leave reverse objects in their\n    current pool.\nWhen omitted, the mode configured on the mask applies. If that mode\nasks for a decision, **fylr** answers with a `202` response and\nexpects the request to be resent with this parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "reverse_pool_changed_always",
                "reverse_pool_changed_never"
              ]
            }
          },
          {
            "name": "objecttype",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Name of the object type, as defined in the instance's datamodel.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "One or more objects to create or update.",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/DbObject"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The objects were created or updated successfully. The response is an\narray of the stored objects.\n",
            "headers": {
              "X-Fylr-Error": {
                "schema": {
                  "type": "string"
                },
                "description": "Only present when `await_index` was set and the wait could not be\ncompleted within the given seconds: the change is stored, but it\nmay not be reflected in the search index yet. The value describes\nthe unfinished wait.\n"
              },
              "X-Fylr-Error-Code": {
                "schema": {
                  "type": "string"
                },
                "description": "Machine-readable companion of `X-Fylr-Error`, only present\ntogether with it: `queue.AwaitIndexTimeout` when the index jobs\nwere not processed within the given seconds,\n`api.AwaitIndexIncomplete` for any other reason the wait could\nnot be completed.\n"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DbObject"
                  }
                }
              }
            }
          },
          "202": {
            "description": "The save cannot be completed until the client confirms a decision. The\nbody is a `response_202`: a list of `tasks`, each with a `title`, a\n`message`, optional `form` fields and `buttons`. A button or form\noption carries, in its `name` and `value`, the query parameter to add\nwhen re-sending the same request. The cases here:\n\n  * **The save would remove your own access** — it changes the\n    object's `_acl` or owner so the requesting user could no longer\n    read or write it. Re-send with `revoke=yes`.\n  * **A workflow transition needs confirmation** — re-send with\n    `confirmTransition=\u003cvalue\u003e`, taking `\u003cvalue\u003e` from the task.\n  * **Reverse-nested objects would change pool** and the mask leaves\n    the choice to the client — the task offers a\n    `reverse_pool_changed_mode` option; re-send with\n    `reverse_pool_changed_mode=reverse_pool_changed_always` or\n    `=reverse_pool_changed_never`.\n\nIf one save raises both the access and the transition confirmation,\nre-send with the combined `revoke:confirmTransition=yes:\u003cvalue\u003e`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DbPost202"
                }
              }
            }
          },
          "400": {
            "description": "The save request could not be processed. The `code` field of the\nresponse identifies which validation rejected the request. The\nschema below lists the most common codes and shows a concrete\nexample.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UnknownObjecttypeError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/LookupFoundTooManyError"
                    },
                    {
                      "$ref": "#/components/schemas/LookupNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/DatabaseUniqueKeyViolationError"
                    },
                    {
                      "$ref": "#/components/schemas/SchemaInconsistentError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The requesting user is not allowed to perform the operation — they\nlack a required object permission or system right.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "423": {
            "description": "An object affected by the request is locked by a concurrent write\noperation. Retry once the lock is released.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatabaseLockError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete objects of any object type.",
        "description": "Delete objects. Replace `{objecttype}` in the URL with the name of an\nobject type from this instance's datamodel.\n\nThe request body is an array of `[object_id, version, comment]` triples.\nWhen a deleted object is still linked from other objects, `delete_policy`\ndecides what happens to those links; without it **fylr** answers with a\n`202` describing the choices.\n\nDiffers from easydb 5: deleting an object that is still referenced from\nanother object is resolved through the `delete_policy` parameter (with a\n`202` describing the choices when it is omitted). easydb 5 has no\n`delete_policy` and instead rejects the deletion with HTTP `409`.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "objecttype",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Name of the object type, as defined in the instance's datamodel.\n"
          },
          {
            "name": "delete_policy",
            "in": "query",
            "description": "Decides what happens to objects and links affected by the deletion.\n  * `remove`: also delete objects that link to a deleted object.\n  * `setnull`: keep the linking objects but clear their link.\n  * `create_collection`: collect the affected objects in a new\n    collection instead of deleting them.\n  * `undelete`: restore previously deleted objects.\n  * `purge`: permanently remove objects from the trash.\nWhen omitted, **fylr** answers with a `202` response describing the\nchoices instead of deleting anything.\n",
            "schema": {
              "type": "string",
              "enum": [
                "remove",
                "setnull",
                "create_collection",
                "undelete",
                "purge"
              ]
            }
          },
          {
            "name": "confirmTransition",
            "in": "query",
            "description": "Confirmation token for a workflow transition triggered by the\ndeletion. Resend the request with the value taken from the `202`\nresponse.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "await_index",
            "in": "query",
            "description": "Maximum number of seconds to wait until the search-index jobs queued\nby this deletion have been processed and the touched indices have\nbeen refreshed: the deletion is reflected in `/api/search` results\nwhen the response arrives. On timeout the request still succeeds —\nthe deletion is carried out, it is only not reflected in the search\nyet — and the response carries the `X-Fylr-Error` /\n`X-Fylr-Error-Code` headers describing the unfinished wait.\n",
            "schema": {
              "type": "integer",
              "format": "int64",
              "example": 60
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Array of `[object_id, version, comment]` triples identifying the\nobjects to delete.\n",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "array",
                  "minItems": 3,
                  "maxItems": 3,
                  "description": "A triple of object ID (integer), version (integer) and an\noptional deletion comment (string or `null`).\n",
                  "items": {
                    "nullable": true,
                    "description": "Triple element: object ID and version are integers, the\ntrailing comment is a string or `null`.\n"
                  }
                }
              },
              "example": [
                [
                  4711,
                  3,
                  "removed obsolete record"
                ],
                [
                  4712,
                  1,
                  null
                ]
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "The objects were deleted. The response summarises which objects were\nremoved and which links were cleared.\n",
            "headers": {
              "X-Fylr-Error": {
                "schema": {
                  "type": "string"
                },
                "description": "Only present when `await_index` was set and the wait could not be\ncompleted within the given seconds: the change is stored, but it\nmay not be reflected in the search index yet. The value describes\nthe unfinished wait.\n"
              },
              "X-Fylr-Error-Code": {
                "schema": {
                  "type": "string"
                },
                "description": "Machine-readable companion of `X-Fylr-Error`, only present\ntogether with it: `queue.AwaitIndexTimeout` when the index jobs\nwere not processed within the given seconds,\n`api.AwaitIndexIncomplete` for any other reason the wait could\nnot be completed.\n"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "policy": {
                      "type": "string",
                      "description": "The `delete_policy` that was applied."
                    },
                    "removed": {
                      "type": "array",
                      "description": "System object IDs of the objects that were removed.\n",
                      "items": {
                        "type": "integer",
                        "format": "int64"
                      }
                    },
                    "setnull": {
                      "type": "array",
                      "description": "System object IDs of objects whose link to a removed\nobject was cleared.\n",
                      "items": {
                        "type": "integer",
                        "format": "int64"
                      }
                    },
                    "create_collection": {
                      "type": "integer",
                      "format": "int64",
                      "description": "With `delete_policy=create_collection`, the ID of the\ntop-level collection created for the affected objects.\n"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The deletion cannot be completed until the client confirms a decision.\nThe body is a `response_202`: a list of `tasks`, each with a `title`,\na `message`, optional `form` fields and `buttons`; a form option or\nbutton supplies, in its `name` and `value`, the query parameter to add\nwhen re-sending the request. The cases here:\n\n  * **No `delete_policy` was given and the objects are still linked**\n    from others — the task offers a `delete_policy` choice: `remove`\n    (also delete the linking objects), `setnull` (keep them but clear\n    their link) or `create_collection` (collect the affected objects\n    instead of deleting them). Re-send with `delete_policy=\u003cchoice\u003e`.\n  * **A workflow transition needs confirmation** — re-send with\n    `confirmTransition=\u003cvalue\u003e`; a `delete_policy` already chosen is\n    carried over automatically.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DbDelete202"
                }
              }
            }
          },
          "400": {
            "description": "The delete request could not be processed. The `code` field of the\nresponse identifies which validation rejected the request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UnknownObjecttypeError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/LookupFoundTooManyError"
                    },
                    {
                      "$ref": "#/components/schemas/LookupNotFoundError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The requesting user is not allowed to perform the operation — they\nlack a required object permission or system right.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "423": {
            "description": "An object affected by the request is locked by a concurrent write\noperation. Retry once the lock is released.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatabaseLockError"
                }
              }
            }
          }
        }
      }
    },
    "/db/{objecttype}/{mask}/{objectId}": {
      "x-path": "/db",
      "description": "Read a single object of any `{objecttype}` from the datamodel, shaped by the\n`{mask}` given in the URL. `{objectId}` is the object's `_id`; the\n`system_object_id` and `global_object_id` addressing forms apply by appending\nthe ID in a further path segment. The response is always an array.\n",
      "get": {
        "summary": "Read a single object of any object type.",
        "description": "Load one object. Replace `{objecttype}` with an object type from the\ndatamodel and `{mask}` with one of its masks.\n\n`objectId` is the object's `_id`. The `system_object_id` and\n`global_object_id` addressing forms (with the ID in a further path\nsegment) apply here as well.\n\nThe response is always an array: empty when no object matches, and with\nmore than one entry when `all_versions` is set.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "objecttype",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Name of the object type, as defined in the instance's datamodel.\n"
          },
          {
            "name": "mask",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Name of the mask that shapes the object. The mask decides which fields are\npresent and whether each field is writable or read-only.\n"
          },
          {
            "name": "objectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `_id` of the object to load. Alternatively pass `system_object_id` or\n`global_object_id` here and supply the actual ID in a following path segment.\n"
          },
          {
            "name": "format",
            "in": "query",
            "description": "Render format for the objects returned in the response.\n\nDiffers from easydb 5: **fylr** additionally offers\n`standard_extended`, `long_inheritance` and `full_inheritance`. easydb\n5 documents only `short`, `standard`, `long` and `full`.\n",
            "schema": {
              "type": "string",
              "default": "full",
              "enum": [
                "short",
                "standard",
                "standard_extended",
                "long",
                "long_inheritance",
                "full",
                "full_inheritance"
              ]
            }
          },
          {
            "name": "file_url_expire",
            "in": "query",
            "description": "Number of days the signed file URLs contained in the response stay\nvalid. If omitted, the expiry configured for the instance is used.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip_reverse_nested",
            "in": "query",
            "description": "If set, **fylr** does not load and return reverse-nested objects in\nthe response. Speeds up the response when the client does not need the\nnested reverse objects.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "all_versions",
            "in": "query",
            "description": "If set, **fylr** returns every stored version of the matched objects\ninstead of only the latest one.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "version",
            "in": "query",
            "description": "Load this specific `_version` of the object instead of the latest\none.\n",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          },
          {
            "name": "latest_linked",
            "in": "query",
            "description": "If set, linked objects are loaded in their latest version even when a\nhistoric `version` of the top level object is requested.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "merge_linked_objects",
            "in": "query",
            "description": "Controls whether linked objects are embedded into the returned\nobjects rather than only referenced.\n",
            "schema": {
              "type": "string",
              "default": "none",
              "enum": [
                "none",
                "in_main_search",
                "not_in_main_search",
                "not_in_main_search_unless_reverse",
                "all"
              ]
            }
          },
          {
            "name": "merge_max_depth",
            "in": "query",
            "description": "Maximum depth up to which linked objects are embedded when\n`merge_linked_objects` is used.\n",
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The matched object. The response is an array and is empty when no\nobject matches.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DbObject"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed — typically an unknown object\ntype or mask, or an invalid query parameter.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnknownObjecttypeError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The requesting user is not allowed to perform the operation — they\nlack a required object permission or system right.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/db/{objecttype}/{mask}/list": {
      "x-path": "/db",
      "description": "List objects of any `{objecttype}` from the datamodel, shaped by the\n`{mask}` given in the URL. Page through the result with `limit` and `offset`.\nOnly objects the requesting user may read are returned, so a page can hold\nfewer than `limit` entries.\n",
      "get": {
        "summary": "List objects of any object type.",
        "description": "Load a page of objects. Replace `{objecttype}` with an object type from\nthe datamodel and `{mask}` with one of its masks. Use `limit` and\n`offset` to page through the result.\n\nOnly objects the requesting user is allowed to read are returned, so a\npage can contain fewer than `limit` entries.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "objecttype",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Name of the object type, as defined in the instance's datamodel.\n"
          },
          {
            "name": "mask",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Name of the mask that shapes the object. The mask decides which fields are\npresent and whether each field is writable or read-only.\n"
          },
          {
            "name": "format",
            "in": "query",
            "description": "Render format for the objects returned in the response.\n\nDiffers from easydb 5: **fylr** additionally offers\n`standard_extended`, `long_inheritance` and `full_inheritance`. easydb\n5 documents only `short`, `standard`, `long` and `full`.\n",
            "schema": {
              "type": "string",
              "default": "full",
              "enum": [
                "short",
                "standard",
                "standard_extended",
                "long",
                "long_inheritance",
                "full",
                "full_inheritance"
              ]
            }
          },
          {
            "name": "file_url_expire",
            "in": "query",
            "description": "Number of days the signed file URLs contained in the response stay\nvalid. If omitted, the expiry configured for the instance is used.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip_reverse_nested",
            "in": "query",
            "description": "If set, **fylr** does not load and return reverse-nested objects in\nthe response. Speeds up the response when the client does not need the\nnested reverse objects.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "all_versions",
            "in": "query",
            "description": "If set, **fylr** returns every stored version of the matched objects\ninstead of only the latest one.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of objects to return.\n",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "default": 1000
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Number of objects to skip before the first returned object.\n",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "files_real_url",
            "in": "query",
            "description": "If set, files that are *left on remote* (leave-on-remote) are returned\nwith their real upstream URL — e.g. the S3 or foreign-http location\nwhere the bytes actually live — instead of this instance's download\nURL, so a backup can recreate them as leave on restore. Non-leave\nfiles are unaffected.\n\nRequires the `system.root` system right: a real upstream URL can be a\npre-signed, direct-access URL that bypasses the per-file ACL. A backup\nsets this by default.\n",
            "schema": {
              "type": "string",
              "format": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of objects, rendered in the requested `format`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DbObject"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed — typically an unknown object\ntype or mask, or an invalid query parameter.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnknownObjecttypeError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The requesting user is not allowed to perform the operation — they\nlack a required object permission or system right.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/eas/{fileId}": {
      "x-path": "/eas",
      "description": "The **eas** endpoint is used to upload and download files. Files are an essential part of a **fylr** system. Files and objects are separate entities. In order to use a file, it must be linked to an object by its `ID`. Files cannot be updated, in case of an update a new file `ID` is issued and linked to the updated object.\n",
      "post": {
        "summary": "Change information about a file. The caller must be allowed to produce the file (its uploader, or a user with write access to a linked object).",
        "description": "Change information about a file. Access is checked via\n`rightcheck.ProduceFile`: the caller passes if it is the file's\nuploader, or if the file is linked to an object on which the caller\nholds both `write` and `asset_upload`. The target file\nmust be an `original`. The body must set at least one of `filename`,\n`reference` or `custom_produce_config`; otherwise the request is\nrejected with `400` (`ServerGeneric`). The patched file is written\nback to the `file` table inside the request transaction, so the\nchange takes effect on commit of this request — there is no working\ncopy and no separate commit step.\n",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "permission_check_only",
            "in": "query",
            "description": "If set, the call is only checking if the current user is allowed to update the file information.\n",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filename": {
                    "type": "string",
                    "description": "The new filename of the file. It is stored as `original_filepath`.\n"
                  },
                  "reference": {
                    "type": "string",
                    "description": "The reference string for the file. Note that the reference is unique across all files in the storage.\n"
                  },
                  "custom_produce_config": {
                    "type": "object",
                    "properties": {
                      "overwrites": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "match": {
                              "type": "object",
                              "description": "If the version matches, the custom parameters overwrite the recipe's parameters. It is mandatory to have at least one parameter set, otherwise this overwrite will be ignored.\n",
                              "properties": {
                                "version_name": {
                                  "type": "string",
                                  "description": "Match the `version`` name.\n"
                                },
                                "version_class": {
                                  "type": "string",
                                  "description": "Match the `class` name.\n"
                                }
                              }
                            },
                            "custom": {
                              "type": "object",
                              "description": "Recipe parameter overrides. Keys are recipe parameter\nnames; values must match the parameter's declared type\nin the recipe definition — so this map is genuinely\nfree-form on the protocol level. See the recipe's own\n`params` block for the names and types it accepts.\n",
                              "additionalProperties": true
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Update was successful.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "description": "Returned if `permission_check_only` was set and the permission check was successful.\n",
                      "properties": {
                        "status": {
                          "type": "object",
                          "properties": {
                            "acknowledged": {
                              "type": "string",
                              "enum": [
                                "ok"
                              ]
                            }
                          },
                          "required": [
                            "acknowledged"
                          ]
                        }
                      },
                      "required": [
                        "status"
                      ]
                    },
                    {
                      "type": "object",
                      "description": "The [file](https://docs.fylr.io/for-developers/system-data-types/file) rendering in `standard` format.\n"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The update could not be processed. Surfaces as `ServerGeneric`\nwhen the body sets none of `filename` / `reference` /\n`custom_produce_config`, when the target file is not an\n`original`, or when the new `filename` would push the file over\nits class size limit; and as `ReadOnlyMode` when the instance is\nread-only.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "The caller is not allowed to produce the file: it is neither the\nuploader nor a user with `write` + `asset_upload` on\na linked object. The `code` is `InsufficientRights` (the caller\ncannot even see the file) or `RightRequired` (visible but not\nwritable). This endpoint returns no `401`; a missing or invalid\ntoken is treated as an anonymous request and rejected with `403`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/InsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Get information about a file. The file is shown if the caller holds `asset_show` or `asset_download` on the original or any version.",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "check_for_duplicates",
            "in": "query",
            "description": "If set, the fylr database is queried for duplicates of the file. The `_duplicate` property will be added to the response.\n",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "mapping",
            "in": "query",
            "description": "If `mapping` is given, the file's metadata is used to compile a `_mapped_metadata` object in the response. `mapping` can either be the `_id` of the mapping or the keyword `standard`. The `standard` mapping will use the object type (and pool i.A.) to determine the standard mapping.\n",
            "schema": {
              "oneOf": [
                {
                  "type": "number",
                  "format": "int64"
                },
                {
                  "type": "string",
                  "enum": [
                    "standard"
                  ]
                }
              ]
            }
          },
          {
            "name": "objecttype",
            "in": "query",
            "description": "The object type for which the mapping is compiled.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mask",
            "in": "query",
            "description": "The `mask` the mapping is compiled for.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pool_id",
            "in": "query",
            "description": "The `pool_id` sets the pool id to determine the mapping if `standard` is requested.\n",
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "format",
            "in": "query",
            "description": "The format of the output. `standard` is the default and includes the `versions` property. `long` includes `metadata` and `versions`. `short` doesn't include neither. If an unknown format is given `short` is used.\n",
            "schema": {
              "type": "string",
              "enum": [
                "short",
                "long",
                "standard"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The response is the file rendering object for the addressed\nfile id (returned directly, not wrapped in a map keyed by id —\nthe keyed map applies only to the multi-id `GET /eas?ids=[...]`).\n\nDiffers from easydb 5: easydb 5 has no single-id path — even one\nasset is fetched via `GET /eas?ids=[...]` and returned as \"A JSON\nobject containing entries for each requested ID\". **fylr** adds\n`GET /eas/{fileId}` and returns the file object directly.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The [file](https://docs.fylr.io/for-developers/system-data-types/file) rendering. Format depends on `format` (default `standard`).\n"
                }
              }
            }
          },
          "403": {
            "description": "The caller may not see the file: it holds neither\n`asset_show` nor `asset_download` on the original or\nany version (and no `deep_link` access applies). The `code` is\n`InsufficientRights`. This endpoint returns no `401`; a missing\nor invalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/produce": {
      "x-path": "/eas/produce",
      "description": "This endpoint is used to produce a new version of the file. It allows to crop and rotate images. The new file gets a new id. The `produce_version` setting from the parent is inherited.\n\nDiffers from easydb 5: easydb 5 accepts a `description` field\n(optional l10n) in the produce body; **fylr** ignores it — the\nrequest only reads `eas_parent_id`, `format`, `transform`,\n`colorspace` and `colorprofile` (the latter two are fylr-only,\nsince 6.34.2).\n",
      "post": {
        "parameters": [
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "eas_parent_id": {
                    "type": "number",
                    "format": "int64",
                    "description": "The file \"original\" the new produced version should be created from.\n"
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "jpg",
                      "jpeg",
                      "jp2",
                      "heic",
                      "png",
                      "tif",
                      "tiff",
                      "bmp",
                      "gif",
                      "psd"
                    ],
                    "description": "The target format of the produced file. Defaults to the\nextension of the file parent. If that extension cannot be\nproduced (for example `jfif`, which can be read but not\nwritten), the default output format of the produce recipe\nis used (`jpg`).\n"
                  },
                  "transform": {
                    "type": "object",
                    "description": "The transformations applied. The order is `rotate-z`, `rotate-x`\nor `rotate-y` and then `crop`.\n",
                    "properties": {
                      "rotate-x": {
                        "type": "number",
                        "format": "int",
                        "description": "If a value other than `0` is given, the image is mirrored on\nthe x-axis (top \u003c-\u003e bottom). This is mutually exclusive with\n`rotate-z`.\n"
                      },
                      "rotate-y": {
                        "type": "number",
                        "format": "int",
                        "description": "If a value other than `0` is given, the image is mirrored on\nthe y-axis (left \u003c-\u003e right). This is mutually exclusive with\n`rotate-x`.\n"
                      },
                      "rotate-z": {
                        "type": "number",
                        "format": "int",
                        "description": "The image is rotated by the given number in degrees. Valid\ndegrees are -360 to 360. For degrees other than multiple of\n90, the background is set to transparent unless the format\ndoesn't support it in which case the background is black.\n"
                      },
                      "crop": {
                        "type": "object",
                        "description": "Crop will cut out the pixels starting at +top +left with the\ngiven width and height. If the cropped rectangle intersects\nwith the dimensions of the image, the intersection is used.\nIf it is outside the image, an image with 1x1 pixel is\nproduced.\n",
                        "properties": {
                          "top": {
                            "type": "number",
                            "format": "int"
                          },
                          "left": {
                            "type": "number",
                            "format": "int"
                          },
                          "width": {
                            "type": "number",
                            "format": "int"
                          },
                          "height": {
                            "type": "number",
                            "format": "int"
                          }
                        }
                      }
                    }
                  },
                  "colorspace": {
                    "type": "string",
                    "enum": [
                      "",
                      "rgb",
                      "sRGB",
                      "cmyk",
                      "gray"
                    ],
                    "description": "Image parents only: target color space. Empty (or omitted)\napplies no color space conversion of its own. `rgb` and\n`sRGB` are fulfilled by the color profile (the explicit\n`colorprofile` or the built-in sRGB default); `cmyk` and\n`gray` convert without embedding a profile unless an\nexplicit matching `colorprofile` is given. Values outside\nthe enum are rejected with `RecipeParamUnsupportedValue`.\n"
                  },
                  "colorprofile": {
                    "type": "string",
                    "description": "Image parents only: name of the ICC color profile for the\nproduced file — a built-in profile (for example\n`eciRGB_v2`) or a profile uploaded in the base\nconfiguration. The profile is converted to and embedded in\nthe produced file and wins over `colorspace`. Empty (or\nomitted) uses the default sRGB profile\n(`sRGB_IEC61966-2-1_black_scaled`); `-` embeds no profile.\nUnknown names are rejected with\n`RecipeParamUnsupportedValue`.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The newly created file will be returned.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The [file](https://docs.fylr.io/for-developers/system-data-types/file) rendering in `long` format.\n"
                }
              }
            }
          },
          "400": {
            "description": "The produce request could not be processed — typical reasons are\n`EasNoParentID` (no / zero `eas_parent_id`), `ProduceOriginalOnly`\n(the parent is not an original), `ProduceExtensionNotSupported`,\n`ProduceFormatNotSupported` and `RecipeParamUnsupportedValue`\n(unknown `colorspace` / `colorprofile`). `ReadOnlyMode` is\nreturned if the instance is read-only. An `eas_parent_id` that\ndoes not match any stored file surfaces as a generic `400` error\n(`ServerGeneric`), not a `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/EasNoParentIDError"
                    },
                    {
                      "$ref": "#/components/schemas/ProduceOriginalOnlyError"
                    },
                    {
                      "$ref": "#/components/schemas/ProduceExtensionNotSupportedError"
                    },
                    {
                      "$ref": "#/components/schemas/ProduceFormatNotSupportedError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "The caller may not produce a version of the parent: it is\nneither the parent's uploader nor a user with `write` +\n`asset_upload` on a linked object. The `code` is\n`InsufficientRights` (the caller cannot even see the parent) or\n`RightRequired` (visible but not producible). This endpoint\nreturns no `401`; a missing or invalid token is treated as an\nanonymous request and rejected with `403`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/InsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/eas/put": {
      "x-path": "/eas/put",
      "description": "The **eas/put** endpoint is used to synchronously upload files.\n\nDiffers from easydb 5: easydb 5 `eas/put` accepts a single file per\nrequest (\"one request must not contain more than one file upload form\nfield\"); **fylr** accepts multiple files in one request (the\n`references` / `filenames` parameters are arrays). Also, easydb 5\nreports a missing user as `400` (\"not authenticated\"); **fylr**\nrejects it with `401` (`UserRequired`).\n",
      "post": {
        "description": "Endpoint to upload one or multiple files. `PUT` and `POST` are identical.",
        "parameters": [
          {
            "name": "references",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of string with a list of references corresponding to each file. File references are unique across all files.\n"
          },
          {
            "name": "filenames",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of string with a list of filenames corresponding to each file. If a\nfilename is a non empty string, the filename delivered by the multi-part is\noverwritten.\n"
          },
          {
            "name": "produce_versions",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of boolean with a list of values corresponding to each file. If set to `true`, fylr produces renditions for each file uploaded, if set to `false`, no versions are produced. If no values is given (no parameter set or less values than needed), `true` is assumed.\n"
          },
          {
            "name": "id_parents",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of integer with a list of parent ids. A parent id must be set for manual rendition uploads when using `version_names`. The id must point to a file \"original\".\n"
          },
          {
            "name": "version_names",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of string with a list of version names corresponding to each file. If a version name is given, the upload is meant to be a manual rendition. As such, the `id_parents` must be given alongside with it. The referenced parent files must be `original` and have set their `produce_versions` to false. Version names must be unique for all manually uploaded versions.\n"
          },
          {
            "name": "custom_produce_configs",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of custom produce config definitions as used in `POST /api/v1/eas/{fileId}`."
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int64",
              "default": 0
            },
            "description": "When adding the renditions job to the file worker queue a priority is used. Set `2` for interactive, `4` for highest and `0` for normal."
          },
          {
            "name": "collection",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int64"
            },
            "description": "Collection is the id of a collection the uploaded files should be linked into.\nThis works like the hotfolder upload into a collection. The collection needs\nto be configured as upload collection. The `_linked_objects` property will be\nset in the response with informations about the created or updated objects the\nfiles have been linked to.\n"
          },
          {
            "name": "check_for_duplicates",
            "in": "query",
            "description": "If set, the fylr database is queried for duplicates of the file. The `_duplicate` property will be added to the response.\n",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file to upload. The `filename` parameter from the `Content-Disposition` header will be used as the file name. Only the base part of the filename is used. The parsing of the path is platform-dependent.\nThe user needs the right to upload a file into the specific class in any of the rights configuration."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upload was successful.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "description": "The [file](https://docs.fylr.io/for-developers/system-data-types/file) rendered in `long` format.\n"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The upload could not be processed. The `code` field identifies\nthe specific reason — for example `FileLimitExceeded`,\n`UploadError`, or `EasNoParentID`. `ReadOnlyMode` is returned\nif the instance is in read-only mode.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/FileLimitExceededError"
                    },
                    {
                      "$ref": "#/components/schemas/UploadError"
                    },
                    {
                      "$ref": "#/components/schemas/EasNoParentIDError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user (`UserRequired`). The upload-right check\nruns before any file is read, so an anonymous request is\nrejected here.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user holds no `asset_upload` anywhere\n(and is neither system root nor `system.poolmanager`). The\n`code` is `RightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RightRequiredError"
                }
              }
            }
          }
        }
      },
      "put": {
        "description": "Endpoint to upload one or multiple files. `PUT` and `POST` are identical.",
        "parameters": [
          {
            "name": "references",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of string with a list of references corresponding to each file. File references are unique across all files.\n"
          },
          {
            "name": "filenames",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of string with a list of filenames corresponding to each file. If a\nfilename is a non empty string, the filename delivered by the multi-part is\noverwritten.\n"
          },
          {
            "name": "produce_versions",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of boolean with a list of values corresponding to each file. If set to `true`, fylr produces renditions for each file uploaded, if set to `false`, no versions are produced. If no values is given (no parameter set or less values than needed), `true` is assumed.\n"
          },
          {
            "name": "id_parents",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of integer with a list of parent ids. A parent id must be set for manual rendition uploads when using `version_names`. The id must point to a file \"original\".\n"
          },
          {
            "name": "version_names",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of string with a list of version names corresponding to each file. If a version name is given, the upload is meant to be a manual rendition. As such, the `id_parents` must be given alongside with it. The referenced parent files must be `original` and have set their `produce_versions` to false. Version names must be unique for all manually uploaded versions.\n"
          },
          {
            "name": "custom_produce_configs",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Array of custom produce config definitions as used in `POST /api/v1/eas/{fileId}`."
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int64",
              "default": 0
            },
            "description": "When adding the renditions job to the file worker queue a priority is used. Set `2` for interactive, `4` for highest and `0` for normal."
          },
          {
            "name": "collection",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int64"
            },
            "description": "Collection is the id of a collection the uploaded files should be linked into.\nThis works like the hotfolder upload into a collection. The collection needs\nto be configured as upload collection. The `_linked_objects` property will be\nset in the response with informations about the created or updated objects the\nfiles have been linked to.\n"
          },
          {
            "name": "check_for_duplicates",
            "in": "query",
            "description": "If set, the fylr database is queried for duplicates of the file. The `_duplicate` property will be added to the response.\n",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file to upload. The `filename` parameter from the `Content-Disposition` header will be used as the file name. Only the base part of the filename is used. The parsing of the path is platform-dependent.\nThe user needs the right to upload a file into the specific class in any of the rights configuration."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upload was successful.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "description": "The [file](https://docs.fylr.io/for-developers/system-data-types/file) rendered in `long` format.\n"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The upload could not be processed. The `code` field identifies\nthe specific reason — for example `FileLimitExceeded`,\n`UploadError`, or `EasNoParentID`. `ReadOnlyMode` is returned\nif the instance is in read-only mode.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/FileLimitExceededError"
                    },
                    {
                      "$ref": "#/components/schemas/UploadError"
                    },
                    {
                      "$ref": "#/components/schemas/EasNoParentIDError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user (`UserRequired`). The upload-right check\nruns before any file is read, so an anonymous request is\nrejected here.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user holds no `asset_upload` anywhere\n(and is neither system root nor `system.poolmanager`). The\n`code` is `RightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/rput": {
      "x-path": "/eas/rput",
      "description": "The **eas/rput** endpoint is used to asynchronously upload files. Use **/eas/put** to synchronously upload files. A file can only be inserted if a filename is provided, either by setting it as query parameter or in the `Content-Disposition` header set by the web server of the URL.\n",
      "post": {
        "parameters": [
          {
            "name": "filename",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The filename to store. The extension of the filename determines the routing for this file. It is the basis for the the permission check as well as the version production. If the filename is omitted, **fylr** will use the filename retrieved by the `HEAD` request which is performend to check the `url`. If `skip_head_request` is used, `filename` is mandatory.\n"
          },
          {
            "name": "leave",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If `leave` is set, the file will not be copied into the **fylr** storage. Use this to manage remote files which are not meant to be copied into fylr storage. Renditions for this file will still be produced by **fylr**.\n"
          },
          {
            "name": "version_name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "If a version name is given, the upload is meant to be a manual rendition. As such, the `id_parents` must be given alongside with it. The referenced parent files must be `original` and have set their `produce_versions` to false. Version names must be unique for all manually uploaded versions.\n"
          },
          {
            "name": "id_parent",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int64"
            },
            "description": "A parent id must be set for manual rendition uploads when using `version_names`. The id must point to a file \"original\".\n"
          },
          {
            "name": "reference",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "A unique file reference to identify the file. It can be used in file lookups when linking files to objects.\n"
          },
          {
            "name": "skip_duplicate_reference",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If set, this setting avoids unique constraints error from duplicate reference. Instead, if a duplicate is encountered the response loads the exsting file and\nmarks it notes that in `_duplicates`.\n\nIf `/rput/bulk` is used and the request contains a new file and duplicates of it, all files will be carray the `_duplicates` marker in the response.\n"
          },
          {
            "name": "custom_produce_config",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "Custom produce config is explained in `POST /api/v1/eas/{fileId}`.\n"
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int64",
              "default": 0
            },
            "description": "When adding the renditions job to the file worker queue a priority is used. Set `2` for interactive, `4` for highest and `0` for normal."
          },
          {
            "name": "produce_versions",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "If set to `true`, fylr produces renditions for each file uploaded, if set to `false`, no versions are produced. If no values is given (no parameter set or less values than needed), `true` is assumed.\n"
          },
          {
            "name": "generate_metadata",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "If set to `false`, metadata for this file can be provived in the request body. This is only allowed if `leave` is set to `true` and `produce_versions` to `false`. This is used by **fylr restore** for the fastest mode to (test-)import files from another system.\n"
          },
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "url"
            },
            "description": "The URL to copy the file from. **fylr** is trying to connect to the URL using a `HEAD` request. If a non `200` response is received from that request, a `GET` request is performed (without reading the body).\nIf no `filename` is given, the request is used to determine the filename. If a `filename` without an extension is given, the request is used to determine the extension.\nIf a filename in the `Content-Disposition` header is found, **fylr** used that. If not, the last part of the URL is used to derive a filename. If that name has no extension, **fylr** parses the `Content-Type` header to determine a file extension from the provided MIME type. The `Content-Type` header also sets the MIME type of the file in the database.\nThe `Content-Length` header is used to set the filesize of the file. If `leave` is set, the `Content-Length` header with a filesize \u003e 0 is required. If `leave` is not set, the `Content-Length` header can be missing. If it is there, it needs to be \u003e 0 too.\nThe host portion of the URL is validated against the `fylr.eas.rput.blockedHosts` config before any outbound request is made. If the host (or any address it resolves to) matches an entry, the call is refused with a `400` error. The compiled-in default blocks loopback, link-local and private (RFC1918 / ULA) ranges; **fylr**'s own internal services (backend callback URL, Elasticsearch nodes, execservers, backend / execserver listener addresses) are added automatically on their exact `host:port`. See `fylr.example.yml` for the entry syntax (IP / CIDR / hostname / single-label wildcard, optional `:port`) and how to override the list.\n"
          },
          {
            "name": "skip_head_request",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If set, **fylr** does not check the validity of the URL by performing the `HEAD` request to the remote server. If set, providing a `filename` is required. This can be used to speed up file imports.\n"
          }
        ],
        "requestBody": {
          "description": "The body may contain the metadata to be stored for this file. If sent, the query parameter `generate_metadata` must be set to `false`.\n",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileMetadata"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The file was registered with **fylr**. The response carries\nthe file descriptor in `long` format.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/file"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The remote upload could not be processed. The `code` field\nidentifies the specific reason — typically `EasInvalidURL` for a\nmissing or unparseable `url`, `EasEmptyFilename` /\n`EasInvalidFilename` (filename validation), or `EasRputError`\nwhen the upstream URL is blocked by the SSRF list or is\notherwise unreachable. `ReadOnlyMode` is returned if the\ninstance is in read-only mode.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/EasInvalidURLError"
                    },
                    {
                      "$ref": "#/components/schemas/EasEmptyFilenameError"
                    },
                    {
                      "$ref": "#/components/schemas/EasInvalidFilenameError"
                    },
                    {
                      "$ref": "#/components/schemas/EasRputError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user (`UserRequired`). The upload-right check\nruns before the remote URL is fetched, so an anonymous request\nis rejected here.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user holds no `asset_upload` anywhere\n(and is neither system root nor `system.poolmanager`). The\n`code` is `RightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/rput/bulk": {
      "x-path": "/eas/rput/bulk",
      "description": "The **eas/rput/bulk** endpoint is used to asynchronously upload files. It works like **eas/rput** but in bulk. This is the fastest method to upload files into **fylr**.\n",
      "post": {
        "parameters": [
          {
            "name": "skip_duplicate_reference",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If set, this setting avoids unique constraints error from duplicate reference. Instead, if a duplicate is encountered the response loads the exsting file and\nmarks it notes that in `_duplicates`.\n\nIf `/rput/bulk` is used and the request contains a new file and duplicates of it, all files will be carray the `_duplicates` marker in the response.\n"
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int64",
              "default": 0
            },
            "description": "When adding the renditions job to the file worker queue a priority is used. Set `2` for interactive, `4` for highest and `0` for normal."
          }
        ],
        "requestBody": {
          "description": "The body is an array of file descriptors. Files are copied asynchronously from the given urls into **fylr** storage, unless they are marked `leave` in which case the file will not be copied, and only linked into the storage.\n",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "url"
                  ],
                  "properties": {
                    "filename": {
                      "type": "string",
                      "description": "The filename to store. The extension of the filename determines the routing for this file. It is the basis for the the permission check as well as the version production. If the filename is omitted, **fylr** will use the filename retrieved by the `HEAD` request which is performend to check the `url`. If `skip_head_request` is used, `filename` is mandatory.\n"
                    },
                    "leave": {
                      "type": "boolean",
                      "description": "If `leave` is set, the file will not be copied into the **fylr** storage. Use this to manage remote files which are not meant to be copied into fylr storage. Renditions for this file will still be produced by **fylr**.\n"
                    },
                    "version_name": {
                      "type": "string",
                      "description": "If a version name is given, the upload is meant to be a manual rendition. As such, the `id_parents` must be given alongside with it. The referenced parent files must be `original` and have set their `produce_versions` to false. Version names must be unique for all manually uploaded versions.\n"
                    },
                    "id_parent": {
                      "type": "number",
                      "format": "int64",
                      "description": "A parent id must be set for manual rendition uploads when using `version_names`. The id must point to a file \"original\".\n"
                    },
                    "reference": {
                      "type": "string",
                      "description": "A unique file reference to identify the file. It can be used in file lookups when linking files to objects.\n"
                    },
                    "custom_produce_config": {
                      "type": "string",
                      "format": "json",
                      "description": "Custom produce config is explained in `POST /api/v1/eas/{fileId}`.\n"
                    },
                    "produce_versions": {
                      "type": "boolean",
                      "default": true,
                      "description": "If set to `true`, fylr produces renditions for each file uploaded, if set to `false`, no versions are produced. If no values is given (no parameter set or less values than needed), `true` is assumed.\n"
                    },
                    "generate_metadata": {
                      "type": "boolean",
                      "default": true,
                      "description": "If set to `false`, metadata for this file can be provived in the property `metadata`. This is only allowed if `leave` is set to `true` and `produce_versions` to `false`. This is used by **fylr restore** for the fastest mode to (test-)import files from another system.\n"
                    },
                    "url": {
                      "type": "string",
                      "format": "url",
                      "description": "The URL to copy the file from. **fylr** is trying to connect to the URL using a `HEAD` request. If a non `200` response is received from that request, a `GET` request is performed (without reading the body).\nIf no `filename` is given, the request is used to determine the filename. If a `filename` without an extension is given, the request is used to determine the extension.\nIf a filename in the `Content-Disposition` header is found, **fylr** used that. If not, the last part of the URL is used to derive a filename. If that name has no extension, **fylr** parses the `Content-Type` header to determine a file extension from the provided MIME type. The `Content-Type` header also sets the MIME type of the file in the database.\nThe `Content-Length` header is used to set the filesize of the file. If `leave` is set, the `Content-Length` header with a filesize \u003e 0 is required. If `leave` is not set, the `Content-Length` header can be missing. If it is there, it needs to be \u003e 0 too.\nThe host portion of the URL is validated against the `fylr.eas.rput.blockedHosts` config before any outbound request is made. If the host (or any address it resolves to) matches an entry, the call is refused with a `400` error. The compiled-in default blocks loopback, link-local and private (RFC1918 / ULA) ranges; **fylr**'s own internal services (backend callback URL, Elasticsearch nodes, execservers, backend / execserver listener addresses) are added automatically on their exact `host:port`. See `fylr.example.yml` for the entry syntax (IP / CIDR / hostname / single-label wildcard, optional `:port`) and how to override the list.\n"
                    },
                    "skip_head_request": {
                      "type": "boolean",
                      "description": "If set, **fylr** does not check the validity of the URL by performing the `HEAD` request to the remote server. If set, providing a `filename` is required. This can be used to speed up file imports.\n"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/FileMetadata"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The files were registered with **fylr**. The response carries\neach file's descriptor in `long` format (with a `duplicates`\nentry if `skip_duplicate_reference` was set and a match was\nfound).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/file"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The bulk remote upload could not be processed. The `code` field\nidentifies the specific reason — typically `EasInvalidURL` for a\nmissing or unparseable `url`, `EasEmptyFilename` /\n`EasInvalidFilename` (filename validation), or `EasRputError`\nwhen an upstream URL is blocked by the SSRF list or is otherwise\nunreachable. Unlike `/eas/put` and `/eas/rput`, this endpoint\nhas no read-only-mode guard and does not raise `ReadOnlyMode`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/EasInvalidURLError"
                    },
                    {
                      "$ref": "#/components/schemas/EasEmptyFilenameError"
                    },
                    {
                      "$ref": "#/components/schemas/EasInvalidFilenameError"
                    },
                    {
                      "$ref": "#/components/schemas/EasRputError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user (`UserRequired`). The upload-right check\nruns before any remote URL is fetched, so an anonymous request\nis rejected here.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user holds no `asset_upload` anywhere\n(and is neither system root nor `system.poolmanager`). The\n`code` is `RightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/download/{fileId}/{hash}/{version}": {
      "x-path": "/eas/download",
      "description": "The download endpoint is used to deliver binary file data. It delivers data for original files as well as renditions. These URL to the files should be taken from the responses of `/api/db` or `/api/search`.",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recipe",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Name of recipe in the form of `\u003ccookbook\u003e:\u003crecipe\u003e`. If not given, the\nsystem recipe `_produce:produce` is used. In that case, the other url\nparameters are used as parameters for the recipe.\n"
          },
          {
            "name": "recipe_params",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "JSON formatted object which sets the parameters for the recipe. The parameter name is the `\u003ckey\u003e` in the object.\n"
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "jpg",
                "jpeg",
                "jp2",
                "heic",
                "png",
                "tif",
                "tiff",
                "bmp",
                "gif",
                "psd",
                "webp"
              ]
            },
            "description": "The target format of the produced file. Defaults to the extension of the\nfile parent. If that extension cannot be produced (for example `jfif`,\nwhich can be read but not written), the default output format of the\nproduce recipe is used (`jpg`).\n"
          },
          {
            "name": "size",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int"
            },
            "description": "set the target size"
          },
          {
            "name": "width",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int"
            },
            "description": "set the target width"
          },
          {
            "name": "height",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int"
            },
            "description": "set the target height"
          },
          {
            "name": "resize_mode",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "max",
                "min",
                "width",
                "height",
                "cover",
                "force",
                "contain"
              ]
            },
            "description": "* \"max\": \"size\" is the maximum side\n* \"min\": \"size\" is the minimum side\n* \"width\": \"size\" is the width * \"height\"\n* \"size\" is the height.\n\nIf \"width\" and \"height\" are given, `resize_mode`` can either be \"cover\"\nor \"force\". \"cover\" will cut of overflowing pixels, \"contain\" will\nnot cut off any pixels and \"force\" will not preserve the aspect\nratio. \"max\" is the default for \"size\" and \"cover\" for \"width\"\nand \"height\".\n"
          },
          {
            "name": "crop",
            "in": "query",
            "schema": {
              "type": "object",
              "properties": {
                "top": {
                  "type": "number",
                  "format": "int"
                },
                "left": {
                  "type": "number",
                  "format": "int"
                },
                "width": {
                  "type": "number",
                  "format": "int"
                },
                "height": {
                  "type": "number",
                  "format": "int"
                }
              }
            }
          },
          {
            "name": "quality",
            "in": "query",
            "schema": {
              "oneOf": [
                {
                  "type": "string",
                  "enum": [
                    "low",
                    "small",
                    "medium",
                    "maximum"
                  ]
                },
                {
                  "type": "number",
                  "format": "int"
                }
              ]
            },
            "description": "Quality is used to set the JPEG quality. **maximum** is 100, **medium** is 75, **small** and **low** are 50.\n"
          },
          {
            "name": "dpi",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "int"
            },
            "description": "DPI of the target image. Values \u003c= 0 are ignored. This sets XResolution, YResolution and ResolutionUnit."
          }
        ],
        "responses": {
          "200": {
            "description": "The response will use the proper mimetype for the file.\n",
            "headers": {
              "X-Fylr-Storage-Location": {
                "description": "Indicates the storage location of the file.\n* If stored locally: contains the numeric ID of the storage location.\n* If stored remotely: contains the string `remote`.\n",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "The binary data of the file."
                }
              }
            }
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The response will use the proper mimetype for the file.\n",
            "headers": {
              "X-Fylr-Storage-Location": {
                "description": "Indicates the storage location of the file.\n* If stored locally: contains the numeric ID of the storage location.\n* If stored remotely: contains the string `remote`.\n",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/download/{fileId}/{hash}/{version}/{zippath+}": {
      "x-path": "/eas/download",
      "description": "The download endpoint is used to deliver binary file data. It delivers data for original files as well as renditions. These URL to the files should be taken from the responses of `/api/db` or `/api/search`.\nIf a `zippath` is given, the specified file or directory is returned. In case of an directory, descriptive JSON is returned for the directory.\n\nThe ZIP is read on demand — **fylr** never unpacks it, and no\nversion has to be produced first. Append the path inside the ZIP to\nthe download URL the file rendering already gives you; a file\nextension such as `.unpack.zip` has no meaning here.\n\nReading into a ZIP requires the file to be stored in a **fylr**\nstorage location. Both filesystem and S3 locations work — the ZIP\ncentral directory is read with range requests. Files that were left\nat their original URL (`leave_on_remote`) never reached a storage\nlocation and are rejected with a generic `400`.\n\nHolding either `asset_show` or `asset_download` on the file is\nenough, so a viewer that may display an asset but not download it\ncan still read into the ZIP. `Range` requests are supported for a\nfile inside the ZIP.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zippath",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Path of a file or directory inside a `zip` file, appended to the\ndownload URL of the ZIP itself. A path to a file delivers that file\nwith its own mimetype, a path to a directory delivers a `JSON`\nlisting of that directory. A trailing `/` on the download URL lists\nthe ZIP's root.\n\nThe ZIP is read on demand, so no version has to be produced and the\nZIP's file extension is irrelevant. The file must be stored in a\n**fylr** storage location though — filesystem and S3 both work, but\na file left at its original URL (`leave_on_remote`) is rejected with\na generic `400`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The response will use the proper mimetype for the file. In case of a directory, the response will be `JSON`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "The name of the file or directory."
                      },
                      "path": {
                        "type": "string",
                        "description": "The full `zippath` of the file or directory."
                      },
                      "size": {
                        "type": "number",
                        "format": "int64",
                        "description": "The size of the file in bytes, omitted for directories."
                      },
                      "mod_time": {
                        "type": "string",
                        "format": "datetime",
                        "description": "The modification time of the file, omitted for directories."
                      },
                      "is_dir": {
                        "type": "boolean",
                        "description": "Indicates if the entry is a file or directory."
                      }
                    }
                  }
                }
              },
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "The binary data of the file."
                }
              }
            }
          },
          "400": {
            "description": "The file cannot serve a path inside its ZIP because it is not\nstored in a **fylr** storage location, or the `zippath` does\nnot exist inside the ZIP. Both surface as generic `400`\nerrors (`code` `ServerGeneric`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerGenericError"
                }
              }
            }
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`. A `zippath` that does not exist inside the ZIP is a\n`400`, not this `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zippath",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Path of a file or directory inside a `zip` file, appended to the\ndownload URL of the ZIP itself. A path to a file delivers that file\nwith its own mimetype, a path to a directory delivers a `JSON`\nlisting of that directory. A trailing `/` on the download URL lists\nthe ZIP's root.\n\nThe ZIP is read on demand, so no version has to be produced and the\nZIP's file extension is irrelevant. The file must be stored in a\n**fylr** storage location though — filesystem and S3 both work, but\na file left at its original URL (`leave_on_remote`) is rejected with\na generic `400`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The response will use the proper mimetype for the file.\n"
          },
          "400": {
            "description": "The file cannot serve a path inside its ZIP because it is not\nstored in a **fylr** storage location, or the `zippath` does\nnot exist inside the ZIP. Both surface as generic `400`\nerrors (`code` `ServerGeneric`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerGenericError"
                }
              }
            }
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`. A `zippath` that does not exist inside the ZIP is a\n`400`, not this `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/{version}/zoom{zoom_viewport}/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. This endpoint uses the default tile size `320`.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/{version}/zoom{zoom_viewport}/size{zoom_tile_size}/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "zoom_tile_size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The tile size for the zoom responses in pixels. Default is `320`.\n"
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/{version}/zoom{zoom_viewport}/avoid_interpolation/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr. This endpoint uses the default tile size `320`.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/{version}/zoom{zoom_viewport}/size{zoom_tile_size}/avoid_interpolation/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "zoom_tile_size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The tile size for the zoom responses in pixels. Default is `320`.\n"
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/{signature}/{version}/zoom{zoom_viewport}/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. This endpoint uses the default tile size `320`.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/{x-fylr-signature}/{version}/zoom{zoom_viewport}/size{zoom_tile_size}/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "zoom_tile_size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The tile size for the zoom responses in pixels. Default is `320`.\n"
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/{x-fylr-signature}/{version}/zoom{zoom_viewport}/avoid_interpolation/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr. This endpoint uses the default tile size `320`.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/{x-fylr-signature}/{version}/zoom{zoom_viewport}/size{zoom_tile_size}/avoid_interpolation/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "zoom_tile_size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The tile size for the zoom responses in pixels. Default is `320`.\n"
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/obj_uuid/{obj_uuid}/{version}/zoom{zoom_viewport}/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. This endpoint uses the default tile size `320`.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/obj_uuid/{obj_uuid}/{version}/zoom{zoom_viewport}/size{zoom_tile_size}/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zoom_tile_size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The tile size for the zoom responses in pixels. Default is `320`.\n"
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/obj_uuid/{obj_uuid}/{version}/zoom{zoom_viewport}/avoid_interpolation/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr. This endpoint uses the default tile size `320`.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/obj_uuid/{obj_uuid}/{version}/zoom{zoom_viewport}/size{zoom_tile_size}/avoid_interpolation/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zoom_tile_size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The tile size for the zoom responses in pixels. Default is `320`.\n"
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/obj_uuid/{obj_uuid}/{x-fylr-signature}/{version}/zoom{zoom_viewport}/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr. This endpoint uses the default tile size `320`.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/obj_uuid/{obj_uuid}/{x-fylr-signature}/{version}/zoom{zoom_viewport}/size{zoom_tile_size}/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "zoom_tile_size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The tile size for the zoom responses in pixels. Default is `320`.\n"
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/obj_uuid/{obj_uuid}/{x-fylr-signature}/{version}/zoom{zoom_viewport}/avoid_interpolation/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr. This endpoint uses the default tile size `320`.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/zoom/{fileId}/{hash}/obj_uuid/{obj_uuid}/{x-fylr-signature}/{version}/zoom{zoom_viewport}/size{zoom_tile_size}/avoid_interpolation/part{zoom_x}x{zoom_y}.{format}": {
      "x-path": "/eas/zoom",
      "description": "The endpoint zoom is used to deliver tiles for images. Use the `/api/db` and `/api/search` endpoints to retrieve the base URL to zoom and add the parameters to pick the tile accordingly. Tiles can be of any size and position. The `avoid_interpolation` part of the URL is there for compabitlity reasons with easydb 5 and currently unsupported in fylr.\n",
      "get": {
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "zoom_tile_size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The tile size for the zoom responses in pixels. Default is `320`.\n"
          },
          {
            "name": "zoom_viewport",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "The viewport is the width of the desired rectangle for the tile selection. The minimum is 100. If the original image width is 4000px and the viewport is 40000px, the zoom factor will be 10. The image is zoomed so that the width of the resulting image is as large as this parameter. "
          },
          {
            "name": "zoom_x",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_x` is the tile number on the x-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "zoom_y",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            },
            "description": "Within the viewport zoomed image `zoom_y` is the tile number on the y-axis on\na tought grid. The tile size is 320 unless given otherwise. If an image is\n3200px (width) x 16000px (height) and the viewport is 32000px, we have a zoom\nfactor of 10. With a tile size of 320, this results in a grid of 100 x 50\ntiles."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpg"
              ]
            },
            "description": "The output format of a tile. The internal compute chain works with a `BMP` without alpha channel. So, the zoomer\nwill not support transparency for `PNG`, but use a white background instead.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/obj_uuid/{obj_uuid}/{x-fylr-signature}/{version}/info.json": {
      "x-path": "/eas/iiif",
      "description": "Serve the [IIIF Image Information](https://iiif.io/api/image/2.0/#image-information)\n(`info.json`) for a file `version`, per the\n[IIIF Image API 2.0](https://iiif.io/api/image/2.0/). Reading the image\nrequires `asset_show`. Tiles and image derivatives are served from the\nsibling `.../{region}/{size}/{rotation}/{quality}.{format}` paths.\n",
      "get": {
        "description": "The [IIIF endpoint](https://iiif.io/api/image/2.0/) serves images and tiles.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "Contains the [IIIF image information](https://iiif.io/api/image/2.0/#image-information).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IiifImageInfo"
                }
              }
            }
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "description": "Same access checks as `GET` (and the same `403` / `404`\nresponses; there is no `401`), but returns no body on success.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The image information exists and is accessible. No response body.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/obj_uuid/{obj_uuid}/{version}/info.json": {
      "x-path": "/eas/iiif",
      "description": "Serve the [IIIF Image Information](https://iiif.io/api/image/2.0/#image-information)\n(`info.json`) for a file `version`, per the\n[IIIF Image API 2.0](https://iiif.io/api/image/2.0/). Reading the image\nrequires `asset_show`. Tiles and image derivatives are served from the\nsibling `.../{region}/{size}/{rotation}/{quality}.{format}` paths.\n",
      "get": {
        "description": "The [IIIF endpoint](https://iiif.io/api/image/2.0/) serves images and tiles.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "Contains the [IIIF image information](https://iiif.io/api/image/2.0/#image-information).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IiifImageInfo"
                }
              }
            }
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "description": "Same access checks as `GET` (and the same `403` / `404`\nresponses; there is no `401`), but returns no body on success.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The image information exists and is accessible. No response body.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/{x-fylr-signature}/{version}/info.json": {
      "x-path": "/eas/iiif",
      "description": "Serve the [IIIF Image Information](https://iiif.io/api/image/2.0/#image-information)\n(`info.json`) for a file `version`, per the\n[IIIF Image API 2.0](https://iiif.io/api/image/2.0/). Reading the image\nrequires `asset_show`. Tiles and image derivatives are served from the\nsibling `.../{region}/{size}/{rotation}/{quality}.{format}` paths.\n",
      "get": {
        "description": "The [IIIF endpoint](https://iiif.io/api/image/2.0/) serves images and tiles.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "Contains the [IIIF image information](https://iiif.io/api/image/2.0/#image-information).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IiifImageInfo"
                }
              }
            }
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "description": "Same access checks as `GET` (and the same `403` / `404`\nresponses; there is no `401`), but returns no body on success.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The image information exists and is accessible. No response body.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/{version}/info.json": {
      "x-path": "/eas/iiif",
      "description": "Serve the [IIIF Image Information](https://iiif.io/api/image/2.0/#image-information)\n(`info.json`) for a file `version`, per the\n[IIIF Image API 2.0](https://iiif.io/api/image/2.0/). Reading the image\nrequires `asset_show`. Tiles and image derivatives are served from the\nsibling `.../{region}/{size}/{rotation}/{quality}.{format}` paths.\n",
      "get": {
        "description": "The [IIIF endpoint](https://iiif.io/api/image/2.0/) serves images and tiles.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "Contains the [IIIF image information](https://iiif.io/api/image/2.0/#image-information).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IiifImageInfo"
                }
              }
            }
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "description": "Same access checks as `GET` (and the same `403` / `404`\nresponses; there is no `401`), but returns no body on success.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The image information exists and is accessible. No response body.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/obj_uuid/{obj_uuid}/{x-fylr-signature}/{version}/{region}/{size}/{rotation}/{quality}.{format}": {
      "x-path": "/eas/iiif",
      "description": "Serve an image derivative for a file `version` per the\n[IIIF Image API 2.0](https://iiif.io/api/image/2.0/): the requested `region`\nis cropped, scaled to `size`, rotated by `rotation` and rendered as\n`quality`.`format`. Reading the image requires `asset_show`. The\n`info.json` paths describe the parameters a given image supports.\n",
      "get": {
        "description": "The [IIIF endpoint](https://iiif.io/api/image/2.0/) serves images and tiles.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "region",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF region](https://iiif.io/api/image/2.0/#region) is a string with `x,y,w,h` and other format. Check the link for more information.\n"
          },
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information.\n"
          },
          {
            "name": "rotation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF rotation](https://iiif.io/api/image/2.0/#rotation) specifies mirroring and rotation. A leading exclamation mark (“!”) indicates that the image should be mirrored by reflection on the vertical axis before any rotation is applied. The numerical value represents the number of degrees of clockwise rotation, and may be any number from 0 to 360. **fylr** only supports integer numbers for rotation. More information can be found in the link."
          },
          {
            "name": "quality",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "default",
                "gray",
                "color",
                "bitonal"
              ]
            },
            "description": "The [IIIF format](https://iiif.io/api/image/2.0/#quality) parameter determines whether the image is delivered in color, grayscale or black and white. Click on the link for more information."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "jpg",
                "tif",
                "png",
                "jp2",
                "pdf",
                "web"
              ]
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information. Formats `jpg` and `png` are delivered with fast code if the quality is set to `color` or `default` and no `rotation` is requested.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "description": "Same access checks as `GET` (and the same `403` / `404`\nresponses; there is no `401`), but returns no body on success.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "region",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF region](https://iiif.io/api/image/2.0/#region) is a string with `x,y,w,h` and other format. Check the link for more information.\n"
          },
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information.\n"
          },
          {
            "name": "rotation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF rotation](https://iiif.io/api/image/2.0/#rotation) specifies mirroring and rotation. A leading exclamation mark (“!”) indicates that the image should be mirrored by reflection on the vertical axis before any rotation is applied. The numerical value represents the number of degrees of clockwise rotation, and may be any number from 0 to 360. **fylr** only supports integer numbers for rotation. More information can be found in the link."
          },
          {
            "name": "quality",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "default",
                "gray",
                "color",
                "bitonal"
              ]
            },
            "description": "The [IIIF format](https://iiif.io/api/image/2.0/#quality) parameter determines whether the image is delivered in color, grayscale or black and white. Click on the link for more information."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "jpg",
                "tif",
                "png",
                "jp2",
                "pdf",
                "web"
              ]
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information. Formats `jpg` and `png` are delivered with fast code if the quality is set to `color` or `default` and no `rotation` is requested.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The tile exists and is accessible. No response body.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/obj_uuid/{obj_uuid}/{version}/{region}/{size}/{rotation}/{quality}.{format}": {
      "x-path": "/eas/iiif",
      "description": "Serve an image derivative for a file `version` per the\n[IIIF Image API 2.0](https://iiif.io/api/image/2.0/): the requested `region`\nis cropped, scaled to `size`, rotated by `rotation` and rendered as\n`quality`.`format`. Reading the image requires `asset_show`. The\n`info.json` paths describe the parameters a given image supports.\n",
      "get": {
        "description": "The [IIIF endpoint](https://iiif.io/api/image/2.0/) serves images and tiles.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "region",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF region](https://iiif.io/api/image/2.0/#region) is a string with `x,y,w,h` and other format. Check the link for more information.\n"
          },
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information.\n"
          },
          {
            "name": "rotation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF rotation](https://iiif.io/api/image/2.0/#rotation) specifies mirroring and rotation. A leading exclamation mark (“!”) indicates that the image should be mirrored by reflection on the vertical axis before any rotation is applied. The numerical value represents the number of degrees of clockwise rotation, and may be any number from 0 to 360. **fylr** only supports integer numbers for rotation. More information can be found in the link."
          },
          {
            "name": "quality",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "default",
                "gray",
                "color",
                "bitonal"
              ]
            },
            "description": "The [IIIF format](https://iiif.io/api/image/2.0/#quality) parameter determines whether the image is delivered in color, grayscale or black and white. Click on the link for more information."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "jpg",
                "tif",
                "png",
                "jp2",
                "pdf",
                "web"
              ]
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information. Formats `jpg` and `png` are delivered with fast code if the quality is set to `color` or `default` and no `rotation` is requested.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "description": "Same access checks as `GET` (and the same `403` / `404`\nresponses; there is no `401`), but returns no body on success.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "region",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF region](https://iiif.io/api/image/2.0/#region) is a string with `x,y,w,h` and other format. Check the link for more information.\n"
          },
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information.\n"
          },
          {
            "name": "rotation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF rotation](https://iiif.io/api/image/2.0/#rotation) specifies mirroring and rotation. A leading exclamation mark (“!”) indicates that the image should be mirrored by reflection on the vertical axis before any rotation is applied. The numerical value represents the number of degrees of clockwise rotation, and may be any number from 0 to 360. **fylr** only supports integer numbers for rotation. More information can be found in the link."
          },
          {
            "name": "quality",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "default",
                "gray",
                "color",
                "bitonal"
              ]
            },
            "description": "The [IIIF format](https://iiif.io/api/image/2.0/#quality) parameter determines whether the image is delivered in color, grayscale or black and white. Click on the link for more information."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "jpg",
                "tif",
                "png",
                "jp2",
                "pdf",
                "web"
              ]
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information. Formats `jpg` and `png` are delivered with fast code if the quality is set to `color` or `default` and no `rotation` is requested.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The tile exists and is accessible. No response body.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/{x-fylr-signature}/{version}/{region}/{size}/{rotation}/{quality}.{format}": {
      "x-path": "/eas/iiif",
      "description": "Serve an image derivative for a file `version` per the\n[IIIF Image API 2.0](https://iiif.io/api/image/2.0/): the requested `region`\nis cropped, scaled to `size`, rotated by `rotation` and rendered as\n`quality`.`format`. Reading the image requires `asset_show`. The\n`info.json` paths describe the parameters a given image supports.\n",
      "get": {
        "description": "The [IIIF endpoint](https://iiif.io/api/image/2.0/) serves images and tiles.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "region",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF region](https://iiif.io/api/image/2.0/#region) is a string with `x,y,w,h` and other format. Check the link for more information.\n"
          },
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information.\n"
          },
          {
            "name": "rotation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF rotation](https://iiif.io/api/image/2.0/#rotation) specifies mirroring and rotation. A leading exclamation mark (“!”) indicates that the image should be mirrored by reflection on the vertical axis before any rotation is applied. The numerical value represents the number of degrees of clockwise rotation, and may be any number from 0 to 360. **fylr** only supports integer numbers for rotation. More information can be found in the link."
          },
          {
            "name": "quality",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "default",
                "gray",
                "color",
                "bitonal"
              ]
            },
            "description": "The [IIIF format](https://iiif.io/api/image/2.0/#quality) parameter determines whether the image is delivered in color, grayscale or black and white. Click on the link for more information."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "jpg",
                "tif",
                "png",
                "jp2",
                "pdf",
                "web"
              ]
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information. Formats `jpg` and `png` are delivered with fast code if the quality is set to `color` or `default` and no `rotation` is requested.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "description": "Same access checks as `GET` (and the same `403` / `404`\nresponses; there is no `401`), but returns no body on success.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "region",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF region](https://iiif.io/api/image/2.0/#region) is a string with `x,y,w,h` and other format. Check the link for more information.\n"
          },
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information.\n"
          },
          {
            "name": "rotation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF rotation](https://iiif.io/api/image/2.0/#rotation) specifies mirroring and rotation. A leading exclamation mark (“!”) indicates that the image should be mirrored by reflection on the vertical axis before any rotation is applied. The numerical value represents the number of degrees of clockwise rotation, and may be any number from 0 to 360. **fylr** only supports integer numbers for rotation. More information can be found in the link."
          },
          {
            "name": "quality",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "default",
                "gray",
                "color",
                "bitonal"
              ]
            },
            "description": "The [IIIF format](https://iiif.io/api/image/2.0/#quality) parameter determines whether the image is delivered in color, grayscale or black and white. Click on the link for more information."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "jpg",
                "tif",
                "png",
                "jp2",
                "pdf",
                "web"
              ]
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information. Formats `jpg` and `png` are delivered with fast code if the quality is set to `color` or `default` and no `rotation` is requested.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The tile exists and is accessible. No response body.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/{version}/{region}/{size}/{rotation}/{quality}.{format}": {
      "x-path": "/eas/iiif",
      "description": "Serve an image derivative for a file `version` per the\n[IIIF Image API 2.0](https://iiif.io/api/image/2.0/): the requested `region`\nis cropped, scaled to `size`, rotated by `rotation` and rendered as\n`quality`.`format`. Reading the image requires `asset_show`. The\n`info.json` paths describe the parameters a given image supports.\n",
      "get": {
        "description": "The [IIIF endpoint](https://iiif.io/api/image/2.0/) serves images and tiles.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "region",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF region](https://iiif.io/api/image/2.0/#region) is a string with `x,y,w,h` and other format. Check the link for more information.\n"
          },
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information.\n"
          },
          {
            "name": "rotation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF rotation](https://iiif.io/api/image/2.0/#rotation) specifies mirroring and rotation. A leading exclamation mark (“!”) indicates that the image should be mirrored by reflection on the vertical axis before any rotation is applied. The numerical value represents the number of degrees of clockwise rotation, and may be any number from 0 to 360. **fylr** only supports integer numbers for rotation. More information can be found in the link."
          },
          {
            "name": "quality",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "default",
                "gray",
                "color",
                "bitonal"
              ]
            },
            "description": "The [IIIF format](https://iiif.io/api/image/2.0/#quality) parameter determines whether the image is delivered in color, grayscale or black and white. Click on the link for more information."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "jpg",
                "tif",
                "png",
                "jp2",
                "pdf",
                "web"
              ]
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information. Formats `jpg` and `png` are delivered with fast code if the quality is set to `color` or `default` and no `rotation` is requested.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The binary data of the tile.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "description": "Same access checks as `GET` (and the same `403` / `404`\nresponses; there is no `401`), but returns no body on success.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "region",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF region](https://iiif.io/api/image/2.0/#region) is a string with `x,y,w,h` and other format. Check the link for more information.\n"
          },
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information.\n"
          },
          {
            "name": "rotation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The [IIIF rotation](https://iiif.io/api/image/2.0/#rotation) specifies mirroring and rotation. A leading exclamation mark (“!”) indicates that the image should be mirrored by reflection on the vertical axis before any rotation is applied. The numerical value represents the number of degrees of clockwise rotation, and may be any number from 0 to 360. **fylr** only supports integer numbers for rotation. More information can be found in the link."
          },
          {
            "name": "quality",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "default",
                "gray",
                "color",
                "bitonal"
              ]
            },
            "description": "The [IIIF format](https://iiif.io/api/image/2.0/#quality) parameter determines whether the image is delivered in color, grayscale or black and white. Click on the link for more information."
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "jpg",
                "tif",
                "png",
                "jp2",
                "pdf",
                "web"
              ]
            },
            "description": "The [IIIF size](https://iiif.io/api/image/2.0/#size) parameter determines the dimensions to which the extracted region is to be scaled. Check the link for more information. Formats `jpg` and `png` are delivered with fast code if the quality is set to `color` or `default` and no `rotation` is requested.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs. The signature will be taken from the query parameter first and if not found, from the request header."
          },
          {
            "name": "x-fylr-signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when\nretrieved through `/api/db`, `/api/search` or other endpoints which deliver\nfylr URLs. The signature will be taken from the query parameter first and if\nnot found, from the request header."
          }
        ],
        "responses": {
          "200": {
            "description": "The tile exists and is accessible. No response body.\n"
          },
          "403": {
            "description": "Access to the file is denied (`code` `InsufficientRights`):\nthe caller holds neither `asset_show` nor `asset_download` on the\nfile (holding either one is enough; anonymous requests are checked\nagainst the `deep_link` user), or the request `hash` / `version`\ndoes not match the stored file, or the `x-fylr-signature` is\ninvalid or expired. This endpoint returns no `401`; a missing or\ninvalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "404": {
            "description": "The addressed file id does not exist. A wrong `hash`, wrong\n`version`, or an invalid / expired signature is a `403`, not\na `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/obj_uuid/{obj_uuid}/{x-fylr-signature}/{version}": {
      "x-path": "/eas/iiif",
      "description": "The base [IIIF](https://iiif.io/api/image/2.0/) resource URL for a file\n`version`, with no trailing path segment. It carries no image itself: any\nrequest is `303`-redirected to the corresponding `info.json`, where the\naccess rights are checked.\n",
      "get": {
        "summary": "Redirect to the IIIF `info.json`.",
        "description": "A IIIF resource URL with no trailing path segment (with or without\na trailing slash) is `303`-redirected to the corresponding\n`info.json`. No access check is performed at this step; the rights\nare checked on the redirected `info.json` request.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          }
        ],
        "responses": {
          "303": {
            "description": "Redirects to `\u003cthis-url\u003e/info.json` via a `Location` header.\n",
            "headers": {
              "Location": {
                "description": "The `info.json` URL for this IIIF resource.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "Redirect to the IIIF `info.json`.",
        "description": "Like `GET` on this redirect URL: `303`-redirected to the\ncorresponding `info.json`.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          }
        ],
        "responses": {
          "303": {
            "description": "Redirects to `\u003cthis-url\u003e/info.json` via a `Location` header.\n",
            "headers": {
              "Location": {
                "description": "The `info.json` URL for this IIIF resource.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/obj_uuid/{obj_uuid}/{version}": {
      "x-path": "/eas/iiif",
      "description": "The base [IIIF](https://iiif.io/api/image/2.0/) resource URL for a file\n`version`, with no trailing path segment. It carries no image itself: any\nrequest is `303`-redirected to the corresponding `info.json`, where the\naccess rights are checked.\n",
      "get": {
        "summary": "Redirect to the IIIF `info.json`.",
        "description": "A IIIF resource URL with no trailing path segment (with or without\na trailing slash) is `303`-redirected to the corresponding\n`info.json`. No access check is performed at this step; the rights\nare checked on the redirected `info.json` request.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          }
        ],
        "responses": {
          "303": {
            "description": "Redirects to `\u003cthis-url\u003e/info.json` via a `Location` header.\n",
            "headers": {
              "Location": {
                "description": "The `info.json` URL for this IIIF resource.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "Redirect to the IIIF `info.json`.",
        "description": "Like `GET` on this redirect URL: `303`-redirected to the\ncorresponding `info.json`.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "obj_uuid",
            "in": "path",
            "required": true,
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          }
        ],
        "responses": {
          "303": {
            "description": "Redirects to `\u003cthis-url\u003e/info.json` via a `Location` header.\n",
            "headers": {
              "Location": {
                "description": "The `info.json` URL for this IIIF resource.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/{x-fylr-signature}/{version}": {
      "x-path": "/eas/iiif",
      "description": "The base [IIIF](https://iiif.io/api/image/2.0/) resource URL for a file\n`version`, with no trailing path segment. It carries no image itself: any\nrequest is `303`-redirected to the corresponding `info.json`, where the\naccess rights are checked.\n",
      "get": {
        "summary": "Redirect to the IIIF `info.json`.",
        "description": "A IIIF resource URL with no trailing path segment (with or without\na trailing slash) is `303`-redirected to the corresponding\n`info.json`. No access check is performed at this step; the rights\nare checked on the redirected `info.json` request.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          }
        ],
        "responses": {
          "303": {
            "description": "Redirects to `\u003cthis-url\u003e/info.json` via a `Location` header.\n",
            "headers": {
              "Location": {
                "description": "The `info.json` URL for this IIIF resource.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "Redirect to the IIIF `info.json`.",
        "description": "Like `GET` on this redirect URL: `303`-redirected to the\ncorresponding `info.json`.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "x-fylr-signature",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The signature to omit file permission checks. It will be added to the URL when retrieved through `/api/db`, `/api/search` or other endpoints which deliver fylr URLs."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          }
        ],
        "responses": {
          "303": {
            "description": "Redirects to `\u003cthis-url\u003e/info.json` via a `Location` header.\n",
            "headers": {
              "Location": {
                "description": "The `info.json` URL for this IIIF resource.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/eas/iiif/{fileId}/{hash}/{version}": {
      "x-path": "/eas/iiif",
      "description": "The base [IIIF](https://iiif.io/api/image/2.0/) resource URL for a file\n`version`, with no trailing path segment. It carries no image itself: any\nrequest is `303`-redirected to the corresponding `info.json`, where the\naccess rights are checked.\n",
      "get": {
        "summary": "Redirect to the IIIF `info.json`.",
        "description": "A IIIF resource URL with no trailing path segment (with or without\na trailing slash) is `303`-redirected to the corresponding\n`info.json`. No access check is performed at this step; the rights\nare checked on the redirected `info.json` request.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          }
        ],
        "responses": {
          "303": {
            "description": "Redirects to `\u003cthis-url\u003e/info.json` via a `Location` header.\n",
            "headers": {
              "Location": {
                "description": "The `info.json` URL for this IIIF resource.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "Redirect to the IIIF `info.json`.",
        "description": "Like `GET` on this redirect URL: `303`-redirected to the\ncorresponding `info.json`.\n",
        "parameters": [
          {
            "name": "fileId",
            "in": "path",
            "description": "The ID of the file.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `hash` is the `file.hash` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `file.class_extension` as described [here](https://docs.fylr.io/for-developers/system-data-types/file#hash)."
          }
        ],
        "responses": {
          "303": {
            "description": "Redirects to `\u003cthis-url\u003e/info.json` via a `Location` header.\n",
            "headers": {
              "Location": {
                "description": "The `info.json` URL for this IIIF resource.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/eas": {
      "x-path": "/eas",
      "description": "Fetch the [file](https://docs.fylr.io/for-developers/system-data-types/file)\nrenderings for several files at once. The file `ids` are passed as a JSON\narray in the query; the response is a map keyed by file `ID`. A file is shown\nif the user holds `asset_show` or `asset_download` on the original\nor on at least one of its versions. There is no blanket login gate: an\nunauthenticated request is served via the `deep_link` system user if deep\nlinking is enabled. Use `GET /eas/{fileId}` to address a single file.\n\nDiffers from easydb 5: easydb 5 requires an authenticated user on\n`GET /eas` (\"The user must be authenticated.\"); **fylr** has no login\ngate here — a missing token is served as the anonymous `deep_link`\nuser, and a denied request is `403` (`InsufficientRights`), never\n`401`.\n",
      "get": {
        "summary": "Get information about a file.",
        "parameters": [
          {
            "name": "ids",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "A json formatted array of file IDs. Example: `[1,3,4]`.\n"
          },
          {
            "name": "obj_uuid",
            "in": "query",
            "description": "The `_uuid` of the object the file is linked into. This is used for the permission check.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "check_for_duplicates",
            "in": "query",
            "description": "If set, the fylr database is queried for duplicates of the file. The `_duplicate` property will be added to the response.\n",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "mapping",
            "in": "query",
            "description": "If `mapping` is given, the file's metadata is used to compile a `_mapped_metadata` object in the response. `mapping` can either be the `_id` of the mapping or the keyword `standard`. The `standard` mapping will use the object type (and pool i.A.) to determine the standard mapping.\n",
            "schema": {
              "oneOf": [
                {
                  "type": "number",
                  "format": "int64"
                },
                {
                  "type": "string",
                  "enum": [
                    "standard"
                  ]
                }
              ]
            }
          },
          {
            "name": "objecttype",
            "in": "query",
            "description": "The object type for which the mapping is compiled.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mask",
            "in": "query",
            "description": "The `mask` the mapping is compiled for.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pool_id",
            "in": "query",
            "description": "The `pool_id` sets the pool id to determine the mapping if `standard` is requested.\n",
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "format",
            "in": "query",
            "description": "The format of the output. `standard` is the default and includes the `versions` property. `long` includes `metadata` and `versions`. `short` doesn't include neither. If an unknown format is given `short` is used.\n",
            "schema": {
              "type": "string",
              "enum": [
                "short",
                "long",
                "standard"
              ]
            }
          },
          {
            "name": "mapping_recipe_configs",
            "in": "query",
            "description": "Configuration for recipes used in the metadata mapping profile. The value must\nbe an JSON-encoded object. See collections for a details description of the\nformat.\n",
            "schema": {
              "type": "object",
              "format": "json"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The response contains the file infos in a map.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "description": "The [file](https://docs.fylr.io/for-developers/system-data-types/file) rendering. The `key` is the file ID.\n"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The caller may not see the file: it holds neither\n`asset_show` nor `asset_download` on the original\nor any version (and no `deep_link` access applies). The `code`\nis `InsufficientRights`. This endpoint returns no `401`; a\nmissing or invalid token is treated as an anonymous request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          }
        }
      }
    },
    "/search": {
      "description": "Run searches over the indexed objects, or over a different domain selected\nby the request `type` (`pool`, `collection`, `event`, `message`, `user`,\n`group` or `acl`). `POST /search` takes a `SearchRequest` body; `GET\n/search` takes the same request as a JSON string in the `BODY` query\nparameter so the call can be cached. Both return a `SearchResponse` with the\ntotal `count` and the requested page of `objects`, restricted to what the\nrequesting user may read.\n\nDiffers from easydb 5: the searchable domains are `pool`, `collection`,\n`event`, `message`, `user`, `group` and `acl` (plus the default object\nsearch). easydb 5 has no `event` domain, and **fylr** has no\n`pool_management` domain (easydb 5 documents `pool_management` to search\npools with `bag_write`).\n",
      "post": {
        "summary": "Search for objects.",
        "description": "Run a search and return the matching objects.\n\nThe request body is a `SearchRequest`. Its `search` property holds a list\nof search elements that are combined into a single boolean query. Each\nelement has a `type` — one of `text`, `in`, `range`, `changelog_range`,\n`complex`, `nested`, `geo_bounding_box` or `geo_shape` (`match` is a\nlegacy alias of `text`) — and a `bool` that decides whether it `must`,\n`should` or `must_not` match. Elements of type `complex` and `nested`\ngroup further elements, so arbitrarily nested queries can be expressed.\n\nBy default the search runs over the indexed objects. Set `type` on the\nrequest to search a different domain instead: `pool`, `collection`,\n`event`, `message`, `user`, `group` or `acl`.\n\nOnly objects the requesting user is allowed to read are returned. The\nresponse reports the total `count` together with the `objects` of the\nrequested page and any requested `aggregations`.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The search to run.\n",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The search ran successfully. The response contains the page of\nmatching objects and the total result `count`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "description": "The search request could not be processed. The `code` field of the\nresponse identifies which validation rejected the request. The\nschema below lists the stable codes and shows a concrete example.\n\nA malformed request body or a structural query error (for example a\nsearch element with a missing or unknown `type`, or an unknown\n`bool`) returns a generic error envelope without one of these stable\ncodes — treat a missing or unknown `code` as a generic bad request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SearchFieldUnknownError"
                    },
                    {
                      "$ref": "#/components/schemas/SearchFieldNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/NestedQueryInError"
                    },
                    {
                      "$ref": "#/components/schemas/WildcardOnlyNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/WildcardExpandedToTooManyTermsError"
                    },
                    {
                      "$ref": "#/components/schemas/UnknownTimezoneError"
                    },
                    {
                      "$ref": "#/components/schemas/DateWrongSyntaxError"
                    },
                    {
                      "$ref": "#/components/schemas/UnsupportedInAggregationError"
                    },
                    {
                      "$ref": "#/components/schemas/ReindexInProgressError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The requesting user lacks a required system right — for example a\nsearch with `type: event` needs `system.api.event[get]`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Search for objects (cacheable).",
        "description": "Same as `POST /search`, but the `SearchRequest` is passed as a JSON\nstring in the `BODY` query parameter instead of in the request body.\nThis makes the request a plain `GET` that clients and intermediate\nproxies can cache.\n\nCaching stays an explicit opt-in: without `cache_seconds` the response\ncarries the default `Cache-Control: no-store, no-cache`. Pass\n`cache_seconds` to let **fylr** answer with\n`Cache-Control: max-age=\u003ccache_seconds\u003e, public` instead.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "BODY",
            "in": "query",
            "required": true,
            "description": "The `SearchRequest`, encoded as a JSON string. The content is the\nsame as the request body of `POST /search`.\n",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cache_seconds",
            "in": "query",
            "description": "When greater than `0`, **fylr** replaces the default\n`Cache-Control: no-store, no-cache` response header with\n`Cache-Control: max-age=\u003ccache_seconds\u003e, public`, so the result\ncan be cached for that many seconds. The parameter works on any\n`GET` endpoint, not just `/search`.\n",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The search ran successfully. The response contains the page of\nmatching objects and the total result `count`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "description": "The search request could not be processed. The `code` field of the\nresponse identifies which validation rejected the request. The\nschema below lists the stable codes and shows a concrete example.\n\nA malformed request body or a structural query error (for example a\nsearch element with a missing or unknown `type`, or an unknown\n`bool`) returns a generic error envelope without one of these stable\ncodes — treat a missing or unknown `code` as a generic bad request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SearchFieldUnknownError"
                    },
                    {
                      "$ref": "#/components/schemas/SearchFieldNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/NestedQueryInError"
                    },
                    {
                      "$ref": "#/components/schemas/WildcardOnlyNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/WildcardExpandedToTooManyTermsError"
                    },
                    {
                      "$ref": "#/components/schemas/UnknownTimezoneError"
                    },
                    {
                      "$ref": "#/components/schemas/DateWrongSyntaxError"
                    },
                    {
                      "$ref": "#/components/schemas/UnsupportedInAggregationError"
                    },
                    {
                      "$ref": "#/components/schemas/ReindexInProgressError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The requesting user lacks a required system right — for example a\nsearch with `type: event` needs `system.api.event[get]`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/search/parse": {
      "x-path": "/search",
      "description": "`/search/parse` accepts a query string written in **fylr**'s search query\nlanguage and turns it into a `SearchRequest`. The language is summarised\nhere.\n\n**Terms.** A bare term searches the full text of all fields:\n\n  * `\"annual report\"` — a quoted string; escape a `\"` inside it with `\\`.\n  * `2024`, `-5`, `1.5` — numbers, integer or decimal.\n\n**Field comparisons.** `\u003cfield\u003e \u003coperator\u003e \u003cvalue\u003e` matches a single\nfield. A field name starts with a letter or `_` and may contain letters,\ndigits, `.`, `:` and `_` (for example `title`, `_pool`, `data.year`). The\nvalue is a string, a number, a geo term, or the literal `null`. Operators:\n\n  * `==` — equals, `!=` — not equals\n  * `=@` — matches, `!@` — does not match\n  * `=*` — contains, `!*` — does not contain\n  * `=^` — starts with, `!^` — does not start with\n  * `\u003e` — greater than, `\u003e=` — greater than or equal\n  * `\u003c` — less than, `\u003c=` — less than or equal\n\nExample: `title =@ \"report\" \u0026\u0026 year \u003e= 2020`\n\n**Boolean operators.** Combine searches with `\u0026\u0026` (and) and `||` (or),\nnegate a single search with `!`, and group with parentheses `( ... )`:\n\n  * `(color == \"red\" || color == \"blue\") \u0026\u0026 !year == 1999`\n\n**Sub-search.** `\u003cfield\u003e ==? ( \u003cquery\u003e )` matches `\u003cfield\u003e` against the\nobjects found by a nested query, for example\n`artist ==? ( country == \"FR\" )`.\n\n**Geo terms.** A geo value compares a geo field against an area:\n\n  * `[lat1,lon1][lat2,lon2]` — a bounding box given by two corner points.\n  * `[\"gkw\",\"syj\"]` — a box spanned by two geohash prefixes.\n  * `[\"gkw\"]` — a single geohash prefix.\n\nWhitespace between tokens (spaces, tabs and newlines) is ignored.\n",
      "post": {
        "summary": "Parse a query string into a search request.",
        "description": "Parse a query string written in **fylr**'s search query language into the\n`SearchRequest` structure that `/search` expects.\n\nWith `search` set to `false` (the default) the parsed `SearchRequest` is\nreturned, so a client can inspect or adjust it before searching. With\n`search` set to `true` the parsed request is executed right away and the\nsearch result is returned instead.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchParseOptions"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The query string was parsed. The response is the parsed\n`SearchRequest` when `search` is `false`, or the search result when\n`search` is `true`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SearchRequest"
                    },
                    {
                      "$ref": "#/components/schemas/SearchResponse"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. More than one failure maps to\nthis status — the `code` field of the response says which one. The\nschema below lists the stable codes and shows a concrete example.\n\nA malformed request body returns a generic error envelope without\none of these stable codes — treat a missing or unknown `code` as a\ngeneric bad request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/QueryParseError"
                    },
                    {
                      "$ref": "#/components/schemas/SearchFieldUnknownError"
                    },
                    {
                      "$ref": "#/components/schemas/SearchFieldNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/NestedQueryInError"
                    },
                    {
                      "$ref": "#/components/schemas/WildcardOnlyNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/WildcardExpandedToTooManyTermsError"
                    },
                    {
                      "$ref": "#/components/schemas/UnknownTimezoneError"
                    },
                    {
                      "$ref": "#/components/schemas/DateWrongSyntaxError"
                    },
                    {
                      "$ref": "#/components/schemas/UnsupportedInAggregationError"
                    },
                    {
                      "$ref": "#/components/schemas/ReindexInProgressError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Parse a query string into a search request.",
        "description": "Same as `POST /search/parse`, but the parse options are passed as query\nparameters instead of in a request body.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          },
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "The query string to parse.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "objecttypes",
            "in": "query",
            "description": "Restrict the search to these object types. Repeat the parameter for\nmore than one object type.\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "If `true`, run the parsed search and return its result instead of the\nparsed `SearchRequest`.\n",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of objects to return.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Number of objects to skip before the first returned object.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "format",
            "in": "query",
            "description": "Render format for the objects in the result.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timezone",
            "in": "query",
            "description": "Timezone used when interpreting dates in the query string.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The query string was parsed. The response is the parsed\n`SearchRequest` when `search` is `false`, or the search result when\n`search` is `true`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SearchRequest"
                    },
                    {
                      "$ref": "#/components/schemas/SearchResponse"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. More than one failure maps to\nthis status — the `code` field of the response says which one. The\nschema below lists the stable codes and shows a concrete example.\n\nA malformed request body returns a generic error envelope without\none of these stable codes — treat a missing or unknown `code` as a\ngeneric bad request.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/QueryParseError"
                    },
                    {
                      "$ref": "#/components/schemas/SearchFieldUnknownError"
                    },
                    {
                      "$ref": "#/components/schemas/SearchFieldNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/NestedQueryInError"
                    },
                    {
                      "$ref": "#/components/schemas/WildcardOnlyNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/WildcardExpandedToTooManyTermsError"
                    },
                    {
                      "$ref": "#/components/schemas/UnknownTimezoneError"
                    },
                    {
                      "$ref": "#/components/schemas/DateWrongSyntaxError"
                    },
                    {
                      "$ref": "#/components/schemas/UnsupportedInAggregationError"
                    },
                    {
                      "$ref": "#/components/schemas/ReindexInProgressError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/search/point_in_time": {
      "x-path": "/search",
      "description": "Manage point-in-time (PIT) search contexts. A PIT is opened by a search\nthat sets `point_in_time` and keeps a stable view of the index across\npaginated requests. `DELETE /search/point_in_time` closes the PIT contexts\nnamed by `pit_id` and frees the resources they hold in the search backend.\n",
      "delete": {
        "summary": "Close point-in-time search contexts.",
        "description": "Close one or more point-in-time (PIT) search contexts. A PIT is opened by\na search that sets `point_in_time` and is used to keep a stable view of\nthe index across paginated requests. Closing a PIT frees the resources it\nholds in the search backend; PITs that are not closed expire on their own\nafter their `keep_alive`.\n",
        "parameters": [
          {
            "name": "x-fylr-authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`. You can also use `authorization`\nwhich does the same. `authorization` is looked at first.\n"
          },
          {
            "name": "authorization",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "The access token in form of `Bearer \u003ctoken\u003e`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "pit_id"
                ],
                "properties": {
                  "pit_id": {
                    "type": "array",
                    "description": "IDs of the point-in-time contexts to close.",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The point-in-time contexts were closed.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "example": "ok"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed — typically a malformed JSON\npayload or a failure from the search backend when closing the\npoint-in-time. The errors raised here are wrapped generic errors,\nso the response uses the standard envelope without a specific\nstable `code`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/settings": {
      "description": "Unauthenticated endpoint reporting brief information about the running fylr\ninstance: `version`, `instance` name, build details, Elastic `index_names`\nand license-derived `capabilities`. The current system status is returned in\nthe `x-fylr-status` response header, which makes this path usable as a\nliveness/status probe.\n",
      "get": {
        "summary": "Get all settings",
        "tags": [
          "settings"
        ],
        "description": "This settings endpoint is unprotected and delivers brief information about\nthe running fylr instance. It can also be used to check the current status\nof the running fylr (no authentication required; suitable for\nliveness/status probes).\n\nDiffers from easydb 5: the response has no `api` field (easydb 5 reports\nan `api` API-version number); fylr exposes only the `version` family\n(`version`, `version_release_date`, `version_full`).\n",
        "responses": {
          "200": {
            "description": "Brief information about the running fylr.\n",
            "headers": {
              "x-fylr-status": {
                "schema": {
                  "type": "string"
                },
                "description": "Current status of the fylr system:\n  * `startup`: Set during startup of fylr. Should rarely be seen.\n  * `reindex`: System is re-indexing. This happens after a `reindex_block` is used during a schema commit.\n    This state is also reached briefly after a regular `reindex`.\n  * `busy`: If too many db connections are open, the system response with `busy`.\n  * `purge`: System is purging (the database is being reset).\n  * `ready`: In this state fylr is ready to answer requests.\n\nOn a `200` settings response the value is in practice `ready` or\n`reindex`. The status reflects a system-wide condition (also\napplied by the global status middleware): `startup`, `purge` and\n`busy` are handled by that middleware as a `503` service\nunavailable before this handler runs, so they are not seen on a\n`200` settings response.\n"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "config_name": {
                      "type": "string",
                      "description": "The internal name of the instace, as set in the base configuration.\n"
                    },
                    "instance": {
                      "type": "string",
                      "description": "The name of the instance as set in the yaml config file.\n"
                    },
                    "version": {
                      "type": "string",
                      "description": "The version of the server. Changed with every release, follows\nsemantic versioning rules.\n"
                    },
                    "version_release_date": {
                      "type": "string",
                      "description": "If known, the release date of this **version**. \u003cunreleased\u003e if not yet released.\n"
                    },
                    "startup_time": {
                      "type": "string",
                      "format": "datetime",
                      "description": "UTC time of when the server was started."
                    },
                    "external_url": {
                      "type": "string",
                      "description": "The url this fylr is reachable under. This is configured in the fylr yaml.\n"
                    },
                    "build_commit": {
                      "type": "string",
                      "description": "The GIT commit hash set at compile time.\n"
                    },
                    "build_commit_time": {
                      "type": "string",
                      "format": "datetime",
                      "description": "The UTC timestamp of the GIT commit hash the fylr was built with.\n"
                    },
                    "name": {
                      "type": "string",
                      "description": "A UID generated when the database is created. The name gets\nre-created when the instance is purged (POST\n**/api/v1/system/purgeall**). This name is used as prefix\nfor Elastic index names.\n"
                    },
                    "num_cpu": {
                      "type": "number",
                      "format": "int",
                      "description": "The number of CPU available for the Go runtime as reported by [runtime.NumCPU](https://pkg.go.dev/runtime#NumCPU).\n"
                    },
                    "index_names": {
                      "type": "object",
                      "description": "Index names as used in the Elatic indexing system. There is\ntwo indexes for reading (BaseRead \u0026 ObjectRead) and two for\nwriting. New writing indexes are created when a reindex is\nstarted. Once that reindex has finished, the read index is\ndeleted and the read index name becomes the write index name.\nIf these names are identical, the index is up to date.\n"
                    },
                    "version_full": {
                      "type": "string",
                      "description": "The full version string including build metadata\n(`global.VersionFull()`).\n"
                    },
                    "solution": {
                      "type": "string",
                      "description": "Legacy field kept for easydb 5 backup/restore\ncompatibility. Omitted when empty.\n"
                    },
                    "capabilities": {
                      "type": "object",
                      "description": "The EFFECTIVE capabilities of this instance — what a\nfrontend can rely on to decide which features to offer.\nHow fylr derives each flag (license, edition, base\nconfig, indexer features) is internal; raw license data\nis not exposed here.\n\nDiffers from fylr before v6.34.0: `indexer_vendor`,\n`indexer_version` and `indexer_geo_support` were\nremoved — `geo_support` now reports the effective value\nand the indexer details moved to `/inspect/system/`.\n",
                      "properties": {
                        "auth": {
                          "type": "boolean",
                          "description": "SAML and LDAP authentication is available."
                        },
                        "ci_hub": {
                          "type": "boolean",
                          "description": "The CI Hub client is available."
                        },
                        "linkrui": {
                          "type": "boolean",
                          "description": "LinkrUI (Santa Cruz Software) is available."
                        },
                        "mobile_app": {
                          "type": "boolean",
                          "description": "The FylrApp client is available."
                        },
                        "read_only": {
                          "type": "boolean",
                          "description": "This fylr is restricted to read-only use."
                        },
                        "geo_support": {
                          "type": "boolean",
                          "description": "Geo queries are available: the license allows geo\nsupport AND the configured indexer supports it.\n"
                        },
                        "kubernetes": {
                          "type": "boolean",
                          "description": "Kubernetes (K8s) hosting is available."
                        },
                        "two_factor": {
                          "type": "boolean",
                          "description": "Logins on this instance can use a second factor:\ntwo-factor authentication is licensed, enabled in\nthe base config and at least one method is usable.\n"
                        }
                      }
                    }
                  },
                  "example": {
                    "name": "fa2c7b27-3430-46cc-97fa-cc3f2eeb1c0b",
                    "config_name": "fylr apitest",
                    "startup_time": "2023-03-20T15:31:28Z",
                    "instance": "apitest",
                    "version": "v6.2.6",
                    "external_url": "http://fylr.localhost",
                    "build_commit": "b83beb3f03f541c5c2ee8cc58d5bb17bfe4ab2b0",
                    "build_commit_time": "2023-03-20T13:35:26Z",
                    "index_names": {
                      "BaseRead": "apitest-fa2c7b27-3430-46cc-97fa-cc3f2eeb1c0b-base-1",
                      "BaseWrite": "apitest-fa2c7b27-3430-46cc-97fa-cc3f2eeb1c0b-base-1",
                      "ObjectRead": "apitest-fa2c7b27-3430-46cc-97fa-cc3f2eeb1c0b-object-1",
                      "ObjectWrite": "apitest-fa2c7b27-3430-46cc-97fa-cc3f2eeb1c0b-object-1"
                    },
                    "capabilities": {
                      "geo_support": false,
                      "two_factor": false
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/system/sendmail": {
      "x-path": "/system/sendmail",
      "description": "Sends an email through the fylr server's mail infrastructure, composed as\na multipart message with separate HTML and text bodies and optional\nattachments. Each send writes an `EMAIL_SENT` or `EMAIL_SENT_FAILED` event.\nRequires `system.sendmail` (or `system.root`).\n",
      "post": {
        "summary": "This endpoint sends an mail using the fylr server infrastructure. The mail is composed as multipart mail with separate HTML and text bodies. The user needs the `system.sendmail` or `system.root` system right. After sending an email `EMAIL_SENT` or `EMAIL_SENT_FAILED` event is written.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "from": {
                    "type": "string",
                    "description": "The _From_ address to use in the mail header.\n"
                  },
                  "to": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The _To_ address to use in the mail header.\n"
                  },
                  "cc": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The _Cc_ addresses to use in the mail header.\n"
                  },
                  "bcc": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The _Bcc_ addresses to use in the mail header.\n"
                  },
                  "subject": {
                    "type": "string",
                    "description": "The _Subject_ to use in the mail header.\n"
                  },
                  "html": {
                    "type": "string",
                    "description": "The body of the mail in HTML format. You can reference attachements using the `cid:` semantic. Use the `cid:\u003cURL\u003e` as source for images. If the `cid:` is followed by an URL, the data is requested and attached. The `cid:\u003cURL\u003e` is then replaced with a filename referencing the attachment. If the URL begins with `fylr.externalURL`, the current access token is appended to the URL. With this, local file previews can be accessed and embedded in the email.\n"
                  },
                  "text": {
                    "type": "string",
                    "description": "The body of the mail in TEXT format.\n"
                  },
                  "attachments": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "filename": {
                          "type": "string",
                          "description": "Filename used for this attachment, set in the `Content-Disposition` header of the attachment multipart.\n"
                        },
                        "content-type": {
                          "type": "string",
                          "description": "The `Content-Type` header of the attachment multipart.\n"
                        },
                        "bytes": {
                          "type": "string",
                          "format": "base64",
                          "description": "BASE64 encoded binary data for the attachement.\n"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The mail has been handed over successfully to the MTA (mail transfer agent)\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    }
                  },
                  "required": [
                    "status"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Sending the mail failed. This also writes an `EMAIL_SENT_FAILED`\nevent. See the `code` and `parameters.msg` for the underlying\nreason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailSentError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user holds neither `system.sendmail` nor\n`system.root`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/sendmail/test": {
      "x-path": "/system/sendmail/test",
      "description": "Sends a test email to a single `to` address to verify the mail\nconfiguration. Each send writes an `EMAIL_SENT` or `EMAIL_SENT_FAILED`\nevent. Requires `system.sendmail` (or `system.root`).\n\nDiffers from easydb 5: the dedicated `system.sendmail` right grants this\noperation. In easydb 5 the equivalent `POST /api/v1/settings/sendmail`\nrequired \"an authenticated session with the `system.root` privilege\".\n",
      "post": {
        "summary": "This endpoint sends a test email to one mail address. The user needs the `system.sendmail` or `system.root` system right. After sending an email `EMAIL_SENT` or `EMAIL_SENT_FAILED` event is written.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to": {
                    "type": "string",
                    "description": "The _To_ address to use in the mail header.\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The mail has been handed over successfully to the MTA (mail transfer agent)\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    }
                  },
                  "required": [
                    "status"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Sending the test mail failed. This also writes an\n`EMAIL_SENT_FAILED` event.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailSentError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user holds neither `system.sendmail` nor\n`system.root`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/share_link": {
      "x-path": "/system/share_link",
      "description": "Shortens url paths and generates an url friendly share id to be accessed via\n/share/\u003cshare_id\u003e.\n* The creating user is stored alongside with the share link. If that user is archived\n  the system user `system:deleted_user`.\n* There is no API to revoke an existing share link.\n* Share links are removed only after they expire.\n",
      "post": {
        "description": "Create a new share link.\n",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "path": {
                    "type": "string",
                    "format": "uri-reference",
                    "pattern": "^\\/",
                    "description": "The URI path to shorten, must start with `/`."
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO date and time when the share link expires. Defaults to one year."
                  },
                  "alias": {
                    "type": "string",
                    "pattern": "^[a-zA-Z0-9][a-zA-Z0-9\\-_~\\.]*[a-zA-Z0-9]$",
                    "description": "Optional alias that can be used instead of the randomly generated short id to access the share link. Only charaters defined in [RFC 3968](https://www.rfc-editor.org/rfc/rfc3986#section-2.3) are allowed.\n"
                  }
                },
                "required": [
                  "path"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "New share link entry\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string",
                      "format": "uri-reference",
                      "pattern": "^\\/",
                      "description": "The target path of the share link URL."
                    },
                    "share_id": {
                      "type": "string",
                      "pattern": "^[a-zA-Z0-9]+$",
                      "description": "The randomly generated id that is used to access the link via \u003cexternal_url\u003e/share/\u003cshare_id\u003e.\n"
                    },
                    "alias": {
                      "type": "string",
                      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9\\-_~\\.]*[a-zA-Z0-9]$",
                      "description": "The user set alias to access the link via \u003cexternal_url\u003e/share/\u0026lt;alias\u0026gt;.\n"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Timestamp when the short link was created."
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Timestamp when the short link expires."
                    }
                  },
                  "required": [
                    "path",
                    "share_id",
                    "created_at",
                    "expires_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The share link could not be created. The `code` field identifies\nthe specific validation failure — invalid path, invalid alias,\nexpiration in the past, or a collision with an existing link.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ShareLinkPathInvalidError"
                    },
                    {
                      "$ref": "#/components/schemas/ShareLinkAliasInvalidError"
                    },
                    {
                      "$ref": "#/components/schemas/ShareLinkExpirationDateInPastError"
                    },
                    {
                      "$ref": "#/components/schemas/ShareLinkAlreadyExistsError"
                    },
                    {
                      "$ref": "#/components/schemas/ShareLinkInvalidError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/share_link/{id}": {
      "x-path": "/system/share_link",
      "description": "Resolves a share link by its `id` (the generated short id or a\nuser-set alias) and redirects to the stored target path prefixed with\n`fylr.externalURL`. An unknown or expired `id` yields\n`code: ShareLinkInvalid`.\n",
      "get": {
        "description": "Redirect to url referenced by given id, if available\n",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "Shortened hash or alias set by user"
          }
        ],
        "responses": {
          "301": {
            "description": "Successful redirect",
            "headers": {
              "Location": {
                "description": "Location is the stored path prefix with `fylr.externalURL`.\n",
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "400": {
            "description": "No share link entry for the given id (or it has expired). The\nresponse carries `code: ShareLinkInvalid`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareLinkInvalidError"
                }
              }
            }
          }
        }
      }
    },
    "/system/status": {
      "x-path": "/system",
      "description": "Reports system-wide statistics: stored-object counts per objecttype\nand per basetype, index-queue and file-processing-queue depth, and\nper-index storage sizes. The response also sets the `x-fylr-status`\nheader to the instance's current lifecycle status (one of `startup`,\n`ready`, `purge`, `reindex`, `busy`). Requires `system.root`.\n",
      "get": {
        "summary": "System object/index/file statistics.",
        "description": "Returns counts of stored objects (per objecttype and per\nbasetype), index-queue depth, file processing queue depth and\nper-index storage sizes. Used by the inspect UI's status page\nand by external monitoring.\n\nThe `x-fylr-status` response header carries the instance's\ncurrent lifecycle status word (one of `startup`, `ready`,\n`purge`, `reindex`, `busy`) — not the build / version / capability\ndetails.\n\nRequires `system.root`.\n",
        "responses": {
          "200": {
            "description": "Object, index and file processing statistics. Sets the\n`x-fylr-status` response header to the current lifecycle\nstatus word (`startup`, `ready`, `purge`, `reindex`, `busy`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemStats"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/errortest": {
      "x-path": "/system",
      "description": "Returns a synthetic error (`code: Test`) so a client can verify it\nparses fylr's error envelope correctly.\n",
      "get": {
        "summary": "Trigger a test error (for error-handling validation).",
        "description": "Returns a synthetic error so clients can verify they parse fylr's\nerror envelope correctly. Surfaces under `code: Test`.\n",
        "responses": {
          "400": {
            "description": "The synthetic error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/system/openapi/spec.json": {
      "x-path": "/system",
      "description": "Serves the OpenAPI specification for the v1 API as JSON, the same\ndocument as `/inspect/apidocs/spec/spec.json` but mounted on the API\nsurface. Accessible to a user holding `system.root`, or to anyone\nwhen the base config flag `system.openapi_spec_endpoint.active` is\nenabled.\n",
      "get": {
        "summary": "The OpenAPI specification for the v1 API (JSON).",
        "description": "Returns the same JSON spec as `/inspect/apidocs/spec/spec.json`,\nmounted under the API surface.\n\nAccess requires the `system.root` right, OR the base config flag\n`system.openapi_spec_endpoint.active` to be enabled — in which\ncase the endpoint is reachable without authentication.\n",
        "responses": {
          "200": {
            "description": "The OpenAPI 3.1 document for this fylr instance, as JSON.\nThe body is a full OpenAPI spec — too large to model inline;\nconsume it with an OpenAPI parser.\n",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `system.root` right and the base\nconfig flag `system.openapi_spec_endpoint.active` is not\nenabled. The response carries `code: InsufficientRights`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          }
        }
      }
    },
    "/system/reindex": {
      "x-path": "/system",
      "description": "Drops the search index into a freshly created one and starts a full\nreindexing run. The run executes asynchronously; the call returns once\nit has been started. Pass `blockFrontend=true` to serve a maintenance\npage on the frontend until the reindex completes.\n\nDiffers from easydb 5: the handler performs no rights check and needs\nno enable flag. In easydb 5 the equivalent `POST /api/v1/settings/reindex`\nrequired a `system.root` session and the server-config flag\n`server.api.settings.reindex` set to `true`.\n",
      "post": {
        "summary": "Rebuild the search index from scratch.",
        "description": "Drops the search index into a freshly created one and triggers a\nfull reindexing run. The reindexing work runs asynchronously on\nthe server; the call returns as soon as the run has been started.\nThe frontend can be blocked while the reindex is in progress so\nusers do not see partial results.\n\nThis operation performs no rights check in the handler today.\n",
        "parameters": [
          {
            "name": "blockFrontend",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "If `true`, fylr serves a maintenance page on the frontend\nuntil the reindex completes.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The reindexing run was started.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/system/purgeall": {
      "x-path": "/system",
      "description": "Wipes the entire instance: drops the search index, optionally purges\nfile storage, and resets the database to an empty state, then\nre-initializes a fresh instance. This is a full factory reset, not a\ncleanup of soft-deleted records. Restricted to the `system:root`\nuser and cannot be undone. Purging must additionally be enabled in\nthe configuration (yml `fylr.allowpurge` and base config\n`system.purge.allow_purge`), otherwise the call is rejected with\n`code: PurgeNotAllowed`.\n\nDiffers from easydb 5: holding the `system.root` right is not enough —\nthe caller must be the actual `system:root` user, otherwise the call\nreturns `code: PurgeSystemRootOnly`. In easydb 5 the equivalent\n`POST /api/v1/settings/purgeall` required only \"an authenticated session\nwith the `system.root` privilege\".\n",
      "post": {
        "summary": "Wipe and re-initialize the entire instance (factory reset).",
        "description": "Drops the search index, optionally purges file storage (base config\n`system.purge.purge_storage`), resets the database to an empty\nstate and re-initializes a fresh instance. This destroys all\ndata — it is not a cleanup of soft-deleted records. Restricted to\nthe `system:root` user and cannot be undone.\n\nPurging must be enabled in the configuration: both the yml\n`fylr.allowpurge` and the base config `system.purge.allow_purge`\nmust be set, otherwise the call returns `code: PurgeNotAllowed`.\n",
        "parameters": [
          {
            "name": "redirect",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Optional URL. If set, the server starts the purge in the\nbackground and immediately responds with a `302` redirect to\nthis URL instead of waiting for the purge to finish.\n"
          },
          {
            "name": "set_password",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Optional new password for the `system:root` user, applied\nafter the instance has been re-initialized.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The purge completed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    }
                  }
                }
              }
            }
          },
          "302": {
            "description": "Returned when a `redirect` value is supplied: the purge runs in\nthe background and the response redirects to the given URL.\n",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "400": {
            "description": "Purging is not enabled in the configuration (yml\n`fylr.allowpurge` and base config `system.purge.allow_purge`).\nThe response carries `code: PurgeNotAllowed`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not allowed to purge. `code: SystemRightRequired`\nif the user lacks `system.root`; `code: PurgeSystemRootOnly`\nif the user holds `system.root` but is not the `system:root`\nuser.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/PurgeSystemRootOnlyError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/system/backup/new": {
      "x-path": "/system",
      "description": "Starts a new backup of the database, files and configuration, stored\nin the configured backup location. The backup runs asynchronously:\nthe call records the backup row and returns its descriptor with a\n`running` status while the archive is produced in the background.\nRequires `system.backup` (or `system.root`).\n",
      "put": {
        "summary": "Create a new backup.",
        "description": "Starts a new backup of the database, files and configuration. The\nbackup runs asynchronously: the call returns the backup descriptor\nwith a `running` status immediately, and the archive is produced in\nthe background and stored in the configured backup location.\nRequires `system.backup` (or `system.root`).\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BackupOptsApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The backup descriptor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupApi"
                }
              }
            }
          },
          "400": {
            "description": "The backup could not be started. `code: FormatNotSupported` if\nthe requested `format` is not one of the supported formats;\notherwise a generic error (`code: ServerGeneric`), for example\nwhen no backup storage location is configured.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/backup/list": {
      "x-path": "/system",
      "description": "Lists the backups on file as an array of backup descriptors. Requires\n`system.backup` (or `system.root`).\n",
      "get": {
        "summary": "List backups on file.",
        "description": "Requires `system.backup` (or `system.root`).\n",
        "responses": {
          "200": {
            "description": "Array of backup descriptors.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BackupApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/backup/{id}": {
      "x-path": "/system",
      "description": "Retrieve or delete a single backup identified by `id`. An unknown `id`\nyields `code: BackupNotFound`. Requires `system.backup` (or\n`system.root`).\n",
      "get": {
        "summary": "Retrieve a backup descriptor.",
        "description": "Requires `system.backup` (or `system.root`).\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The backup descriptor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupApi"
                }
              }
            }
          },
          "404": {
            "description": "The backup id does not exist. The response carries\n`code: BackupNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupNotFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a backup.",
        "description": "Only a backup whose status is `done` or `error` can be deleted.\nRequires `system.backup` (or `system.root`).\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The backup was deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "object",
                      "required": [
                        "acknowledged"
                      ],
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The backup cannot be deleted in its current status (only `done`\nor `error` backups can be deleted). The response carries\n`code: DeleteNotSupported`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "The backup id does not exist. The response carries\n`code: BackupNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupNotFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/backup/{id}/download": {
      "x-path": "/system",
      "description": "Streams the archive bytes of the backup identified by `id` as\n`application/octet-stream`. An unknown `id` yields\n`code: BackupNotFound`. Requires `system.backup` (or `system.root`).\n",
      "get": {
        "summary": "Download a backup archive.",
        "description": "Requires `system.backup` (or `system.root`).\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The backup bytes.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "description": "The backup id does not exist. The response carries\n`code: BackupNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BackupNotFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/location/new": {
      "x-path": "/system",
      "description": "Creates a new storage location; the body `id` must be `0`. A driver\nconnection problem does not block the save — the location is stored\nwith a non-`connected` `status`. Requires `system.location` (or\n`system.root`).\n",
      "post": {
        "summary": "Create a new storage location.",
        "description": "Requires `system.location` (or `system.root`). The `id` in the\nbody must be `0` for a create.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LocationApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created location.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationApi"
                }
              }
            }
          },
          "400": {
            "description": "The location could not be created. `code: LocationMustMatchID`\nif the body `id` does not match the create (`0`);\n`code: LocationReadOnlyCannotBeDefault` if a read-only location\nis configured as a default location; other validation codes\n(unknown driver, missing config, ...) surface their own `code`.\nConnection problems with the configured driver do not block the\nsave — the location is stored with a non-`connected` `status`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/location/list": {
      "x-path": "/system",
      "description": "Lists the configured storage locations as an array. Requires\n`system.location`, `system.config`, or `system.root`.\n",
      "get": {
        "summary": "List configured storage locations.",
        "description": "Requires `system.location`, `system.config`, or `system.root`.\n",
        "responses": {
          "200": {
            "description": "Array of locations.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LocationApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system/location/{id}": {
      "x-path": "/system",
      "description": "Retrieve, update (upsert — the body `id` must equal the path `id`), or\ndelete the storage location identified by `id`. Reading requires\n`system.location`, `system.config`, or `system.root`; writing and\ndeleting require `system.location` (or `system.root`).\n",
      "get": {
        "summary": "Retrieve a single storage location.",
        "description": "Requires `system.location`, `system.config`, or `system.root`.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The location.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationApi"
                }
              }
            }
          },
          "404": {
            "description": "No storage location with the given id is configured. The\nresponse carries `code: ResourceNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Update a storage location.",
        "description": "Saves the storage location under the id in the path (an upsert —\nthe body `id` must equal the path id). Requires `system.location`\n(or `system.root`).\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LocationApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated location.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationApi"
                }
              }
            }
          },
          "400": {
            "description": "The location could not be saved. `code: LocationMustMatchID`\nif the body `id` does not match the id in the path;\n`code: LocationReadOnlyCannotBeDefault` if a read-only\nlocation is configured as a default location; other\nvalidation codes surface their own `code`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a storage location.",
        "description": "Requires `system.location` (or `system.root`).\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The location was deleted. A delete for an id that is not\nconfigured also returns 200 (no row is removed).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "object",
                      "required": [
                        "acknowledged"
                      ],
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (typically `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/system": {
      "x-path": "/system",
      "description": "System-administration endpoints for operating a fylr instance:\nstatistics and status, search-index rebuild, backups, storage\nlocations, share links, sending mail, and wiping the instance\n(factory reset). Most operations require a `system.*` right (often\n`system.root`).\n"
    },
    "/group": {
      "description": "Manage user **groups**. A group bundles a set of users together so\nthey can be addressed by the ACL system. Each group has an owner\n(`_owner`), an optional set of ACL items (`_acl`), system rights\n(`_system_rights`), auth-method group mappings (`_auth_method_group_maps`)\nand IP/subnet filters (`_ip_subnet_filter`). Groups are stored in the\n`group` table; create / update / delete take effect immediately on the\nrequest transaction (there is no working-copy / commit step).\n\nCreating, updating (`POST` / `PUT`) and deleting (`DELETE`) groups\nrequire the `system.group` (or `system.root`) system right. Listing and\nreading groups (`GET`) require no system right — the results are filtered\nto the groups the current session may read (`bag_read`); a `system.root`\nuser sees all groups.\n\nDiffers from easydb 5: easydb 5 requires an authenticated session with\nthe `system.group` right to read groups. fylr requires no system right\non `GET`; an unauthenticated list request returns an empty array rather\nthan an error.\n",
      "post": {
        "summary": "Create or update one or more groups.",
        "description": "The payload is an array of group objects. Whether a group is created\nor updated is decided by `group._version`: a group sent with\n`_version: 1` is created; a group sent with a higher `_version` is\nupdated and its `group._version` must equal the stored version + 1,\notherwise the request fails with a 400 `code: VersionMismatch`. An\nupdate also requires the stored `group._id` (or a `lookup:_id` object\nthat resolves one). The response carries the saved groups with their\n`_id` / `_version` populated.\n\nCreating a group of `type: system` is rejected with a 400\n`code: GroupTypeNotAllowed`; changing a stored group's `type` is\nrejected with a 400 `code: GroupTypeChangeNotAllowed`.\n\n`PUT /group` is an exact alias — same handler, same semantics.\n\nDiffers from easydb 5: in easydb 5 the HTTP method selects the\noperation (`PUT` creates, `POST` updates). In fylr both methods run\nthe same handler and the operation is chosen per group by\n`group._version`, so a single array may mix creates and updates.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/GroupApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The groups were saved. The response carries the saved groups\nwith their `_id` / `_version` populated.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/GroupApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Common causes and their\n`code`: a `group._version` that is not stored version + 1 on\nupdate (`VersionMismatch`); creating a `type: system` group\n(`GroupTypeNotAllowed`) or changing a stored group's `type`\n(`GroupTypeChangeNotAllowed`); deleting a `type: system` group\n(`DeleteSystemGroup`); the instance being in read-only mode\n(`ReadOnlyMode`). A malformed payload or a group id in the URL\nthat matches no stored group surfaces as `code: ServerGeneric`\n(there is no dedicated 404 for a missing group).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/VersionMismatchError"
                    },
                    {
                      "$ref": "#/components/schemas/GroupTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/GroupTypeChangeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteSystemGroupError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required right. Create / update\n(`POST` / `PUT`) and delete (`DELETE`) first require the\n`system.group` (or `system.root`) system right; missing it yields\n`code: SystemRightRequired` with `parameters.rights` listing the\naccepted rights. A non-root user is then checked further:\ncreating needs `system.group[create]` (and `[create_acl]` /\n`[create_system_rights]` when `_acl` / `_system_rights` are sent),\nediting an existing group's `_acl` / `_system_rights` needs\n`system.group[edit_acl]` / `[edit_system_rights]` — these also\nsurface as `SystemRightRequired`. Per-group ACL failures use\n`code: RightRequired`: `bag_read` on read, `bag_write` on update,\n`delete` on delete; changing a group's owner additionally requires\n`system.root`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create or update one or more groups (alias for POST).",
        "description": "Identical semantics to `POST /group`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/GroupApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The groups were saved. The response carries the saved groups\nwith their `_id` / `_version` populated.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/GroupApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Common causes and their\n`code`: a `group._version` that is not stored version + 1 on\nupdate (`VersionMismatch`); creating a `type: system` group\n(`GroupTypeNotAllowed`) or changing a stored group's `type`\n(`GroupTypeChangeNotAllowed`); deleting a `type: system` group\n(`DeleteSystemGroup`); the instance being in read-only mode\n(`ReadOnlyMode`). A malformed payload or a group id in the URL\nthat matches no stored group surfaces as `code: ServerGeneric`\n(there is no dedicated 404 for a missing group).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/VersionMismatchError"
                    },
                    {
                      "$ref": "#/components/schemas/GroupTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/GroupTypeChangeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteSystemGroupError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required right. Create / update\n(`POST` / `PUT`) and delete (`DELETE`) first require the\n`system.group` (or `system.root`) system right; missing it yields\n`code: SystemRightRequired` with `parameters.rights` listing the\naccepted rights. A non-root user is then checked further:\ncreating needs `system.group[create]` (and `[create_acl]` /\n`[create_system_rights]` when `_acl` / `_system_rights` are sent),\nediting an existing group's `_acl` / `_system_rights` needs\n`system.group[edit_acl]` / `[edit_system_rights]` — these also\nsurface as `SystemRightRequired`. Per-group ACL failures use\n`code: RightRequired`: `bag_read` on read, `bag_write` on update,\n`delete` on delete; changing a group's owner additionally requires\n`system.root`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List all groups visible to the current session.",
        "description": "Returns the groups the current session may read (`bag_read`); a\n`system.root` user sees all groups. Groups the session may not read\nare silently omitted — no 403 is raised, and an unauthenticated\nrequest simply yields an empty list, not a 401. The result is paged\nwith `limit` / `offset` and can be narrowed to specific group types.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 1000
            },
            "description": "Maximum number of groups to return. Defaults to `1000`.\n"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 0
            },
            "description": "Number of groups to skip before collecting the result page.\nDefaults to `0`.\n"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of group types to return. When set, only\ngroups whose `type` is in the list are returned. Valid types:\n`easydb`, `system`. Example: `type=easydb,system`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Array of all groups visible to the current session.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/GroupApi"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/group/{id}": {
      "x-path": "/group",
      "description": "Read or delete a single group addressed by its `_id` in the URL. `GET`\nreturns the group as a single-element array (subject to the `bag_read`\nACL); `DELETE` removes it (subject to the `delete` ACL), but a group\nwhose `type` is `system` cannot be deleted and yields a 400\n`code: DeleteSystemGroup`. Neither path requires the `system.group`\nsystem right on read; `DELETE` does.\n",
      "get": {
        "summary": "Retrieve a single group by id.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The group's `_id`."
          }
        ],
        "responses": {
          "200": {
            "description": "The group, returned as a single-element array of group objects\n(the same shape as the create / delete responses).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/GroupApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Common causes and their\n`code`: a `group._version` that is not stored version + 1 on\nupdate (`VersionMismatch`); creating a `type: system` group\n(`GroupTypeNotAllowed`) or changing a stored group's `type`\n(`GroupTypeChangeNotAllowed`); deleting a `type: system` group\n(`DeleteSystemGroup`); the instance being in read-only mode\n(`ReadOnlyMode`). A malformed payload or a group id in the URL\nthat matches no stored group surfaces as `code: ServerGeneric`\n(there is no dedicated 404 for a missing group).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/VersionMismatchError"
                    },
                    {
                      "$ref": "#/components/schemas/GroupTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/GroupTypeChangeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteSystemGroupError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required right. Create / update\n(`POST` / `PUT`) and delete (`DELETE`) first require the\n`system.group` (or `system.root`) system right; missing it yields\n`code: SystemRightRequired` with `parameters.rights` listing the\naccepted rights. A non-root user is then checked further:\ncreating needs `system.group[create]` (and `[create_acl]` /\n`[create_system_rights]` when `_acl` / `_system_rights` are sent),\nediting an existing group's `_acl` / `_system_rights` needs\n`system.group[edit_acl]` / `[edit_system_rights]` — these also\nsurface as `SystemRightRequired`. Per-group ACL failures use\n`code: RightRequired`: `bag_read` on read, `bag_write` on update,\n`delete` on delete; changing a group's owner additionally requires\n`system.root`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a group by id.",
        "description": "A group whose `type` is `system` cannot be deleted — attempting to do\nso yields a 400 with `code: DeleteSystemGroup`.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The group's `_id`."
          }
        ],
        "responses": {
          "200": {
            "description": "The group was deleted. The response carries the deleted group as\nan array of group objects (the same shape as the create / read\nresponses).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/GroupApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Common causes and their\n`code`: a `group._version` that is not stored version + 1 on\nupdate (`VersionMismatch`); creating a `type: system` group\n(`GroupTypeNotAllowed`) or changing a stored group's `type`\n(`GroupTypeChangeNotAllowed`); deleting a `type: system` group\n(`DeleteSystemGroup`); the instance being in read-only mode\n(`ReadOnlyMode`). A malformed payload or a group id in the URL\nthat matches no stored group surfaces as `code: ServerGeneric`\n(there is no dedicated 404 for a missing group).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/VersionMismatchError"
                    },
                    {
                      "$ref": "#/components/schemas/GroupTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/GroupTypeChangeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteSystemGroupError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks a required right. Create / update\n(`POST` / `PUT`) and delete (`DELETE`) first require the\n`system.group` (or `system.root`) system right; missing it yields\n`code: SystemRightRequired` with `parameters.rights` listing the\naccepted rights. A non-root user is then checked further:\ncreating needs `system.group[create]` (and `[create_acl]` /\n`[create_system_rights]` when `_acl` / `_system_rights` are sent),\nediting an existing group's `_acl` / `_system_rights` needs\n`system.group[edit_acl]` / `[edit_system_rights]` — these also\nsurface as `SystemRightRequired`. Per-group ACL failures use\n`code: RightRequired`: `bag_read` on read, `bag_write` on update,\n`delete` on delete; changing a group's owner additionally requires\n`system.root`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/user": {
      "description": "Manage user accounts. The required rights differ per operation:\nlisting and reading users need only an authenticated session (reading\nthe password hash via `include_password` requires `system.root`);\ncreating or updating users is governed by a per-user save-right check\n(a user may save their own record, but changing a protected field of it\n— email, `_acl`, `_system_rights`, `_password`, … — still requires the\ncorresponding right); deleting a user requires the `system.user` system\nright (or `system.root`); and changing the password requires the\n`system.user.change_password` system right (or `system.root`). Some\nproperties additionally require `system.root`.\n",
      "post": {
        "summary": "Create or update one or more users.",
        "description": "The payload is an array of user objects. Users with `_id` set are\nupdated; users without `_id` are created. The response carries the\nsaved users.\n\nDiffers from easydb 5: `POST` and `PUT` are aliases and both create\nand update; create vs. update is decided by the presence of `_id`. In\neasydb 5 `PUT /api/v1/user` only creates, `POST /api/v1/user` only\nupdates, and an update must carry the current `_version`.\n",
        "parameters": [
          {
            "name": "confirm",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "ignore_password_requirements"
              ]
            },
            "description": "Set to `ignore_password_requirements` to re-submit a request that\nwas answered with a `202` because a password did not satisfy the\nconfigured complexity rules, saving the user anyway (see the `202`\nresponse).\n"
          },
          {
            "name": "skip_constraints",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If `true`, skip email-format validation on the saved users.\nAllowed only with `system.root`; without it the request fails\nwith a `400` (code `ServerGeneric`).\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/UserApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The users were saved.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UserApi"
                  }
                }
              }
            }
          },
          "202": {
            "description": "A password in the payload does not meet the configured complexity\nrules. Re-send with `confirm=ignore_password_requirements` to save\nthe user anyway.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserPost202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the\nresponse identifies the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UserNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteSystemUserError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeleteSelfError"
                    },
                    {
                      "$ref": "#/components/schemas/UserLimitNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeletePolicyError"
                    },
                    {
                      "$ref": "#/components/schemas/UserArchivedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserPictureNoRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/UserTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UnableToSetPasswordForUserTypeError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnNeedsSystemRootError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnCanNotBeUpdatedError"
                    },
                    {
                      "$ref": "#/components/schemas/NoPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/WrongPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/PasswordChangedRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/UserEmailMalformedError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is not allowed to perform the operation.\nThe exact condition depends on the operation:\n\n  * `GET /user`: only when `include_password=true` and the\n    requester lacks `system.root` — code `SystemRightRequired`.\n  * `GET /user/{id}`: when `include_password=true` and the\n    requester lacks `system.root` (`SystemRightRequired`); or when\n    a non-`system.root` requester neither owns the target user nor\n    holds the per-user `read` ACL right — code `RightRequired`.\n  * `POST` / `PUT /user`: when a non-`system.root` requester lacks\n    the ACL right needed to create or modify a targeted user\n    (linking/unlinking groups, writing another user, or changing\n    an owner) — code `RightRequired`. Other save-right violations\n    (for example modifying a protected field of your own record)\n    are reported as `400`, not `403`.\n  * `DELETE /user/{id}`: when the requester holds neither\n    `system.user` nor `system.root` (`SystemRightRequired`); or\n    when a `system.user`-but-not-`system.root` requester lacks the\n    per-user `delete` ACL right on the target — code\n    `RightRequired`.\n  * `POST /user/change_password`: when the requester lacks the\n    `system.user.change_password` system right (or `system.root`) —\n    code `SystemRightRequired`; or when the new password fails the\n    configured complexity rules — code\n    `PasswordRequirementNotFulfilled` (the `error` message carries\n    the configured password hint).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "The user could not be saved because another user already has\nthe same email or login.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UserDuplicateEmailError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDuplicateLoginError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create or update one or more users (alias for POST).",
        "parameters": [
          {
            "name": "confirm",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "ignore_password_requirements"
              ]
            },
            "description": "Set to `ignore_password_requirements` to re-submit a request that\nwas answered with a `202` because a password did not satisfy the\nconfigured complexity rules, saving the user anyway (see the `202`\nresponse).\n"
          },
          {
            "name": "skip_constraints",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If `true`, skip email-format validation on the saved users.\nAllowed only with `system.root`; without it the request fails\nwith a `400` (code `ServerGeneric`).\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/UserApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The users were saved.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UserApi"
                  }
                }
              }
            }
          },
          "202": {
            "description": "A password in the payload does not meet the configured complexity\nrules. Re-send with `confirm=ignore_password_requirements` to save\nthe user anyway.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserPost202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the\nresponse identifies the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UserNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteSystemUserError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeleteSelfError"
                    },
                    {
                      "$ref": "#/components/schemas/UserLimitNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeletePolicyError"
                    },
                    {
                      "$ref": "#/components/schemas/UserArchivedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserPictureNoRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/UserTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UnableToSetPasswordForUserTypeError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnNeedsSystemRootError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnCanNotBeUpdatedError"
                    },
                    {
                      "$ref": "#/components/schemas/NoPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/WrongPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/PasswordChangedRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/UserEmailMalformedError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is not allowed to perform the operation.\nThe exact condition depends on the operation:\n\n  * `GET /user`: only when `include_password=true` and the\n    requester lacks `system.root` — code `SystemRightRequired`.\n  * `GET /user/{id}`: when `include_password=true` and the\n    requester lacks `system.root` (`SystemRightRequired`); or when\n    a non-`system.root` requester neither owns the target user nor\n    holds the per-user `read` ACL right — code `RightRequired`.\n  * `POST` / `PUT /user`: when a non-`system.root` requester lacks\n    the ACL right needed to create or modify a targeted user\n    (linking/unlinking groups, writing another user, or changing\n    an owner) — code `RightRequired`. Other save-right violations\n    (for example modifying a protected field of your own record)\n    are reported as `400`, not `403`.\n  * `DELETE /user/{id}`: when the requester holds neither\n    `system.user` nor `system.root` (`SystemRightRequired`); or\n    when a `system.user`-but-not-`system.root` requester lacks the\n    per-user `delete` ACL right on the target — code\n    `RightRequired`.\n  * `POST /user/change_password`: when the requester lacks the\n    `system.user.change_password` system right (or `system.root`) —\n    code `SystemRightRequired`; or when the new password fails the\n    configured complexity rules — code\n    `PasswordRequirementNotFulfilled` (the `error` message carries\n    the configured password hint).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "409": {
            "description": "The user could not be saved because another user already has\nthe same email or login.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UserDuplicateEmailError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDuplicateLoginError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List all users visible to the authenticated user.",
        "description": "Differs from easydb 5: listing requires only an authenticated\nsession, not the `system.user` `read` right. The filter parameter is\n`group_ids` (easydb 5: `groupids`) and the default `limit` is `100`\n(easydb 5: default and maximum `1000`).\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100
            },
            "description": "Maximum number of users to return. Defaults to `100` when omitted\nor not positive.\n"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Number of users to skip from the start of the result."
          },
          {
            "name": "group_ids",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of group `_id`s; returns only users that are\nmembers of one of the given groups.\n"
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of user types to filter by (for example\n`easydb`).\n"
          },
          {
            "name": "changed_since",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO-8601 timestamp; returns only users whose `_updated_at` is at or\nafter this time.\n"
          },
          {
            "name": "archived_since",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO-8601 timestamp, or the literal `null`. With `null`, only\nnon-archived users are returned. Otherwise returns users whose\n`_archived_at` is at or after the given time.\n"
          },
          {
            "name": "include_password",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If `true`, each entry includes the stored password hash (for\nbackup tooling). Requires `system.root`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Array of all users visible to the current session.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UserApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is not allowed to perform the operation.\nThe exact condition depends on the operation:\n\n  * `GET /user`: only when `include_password=true` and the\n    requester lacks `system.root` — code `SystemRightRequired`.\n  * `GET /user/{id}`: when `include_password=true` and the\n    requester lacks `system.root` (`SystemRightRequired`); or when\n    a non-`system.root` requester neither owns the target user nor\n    holds the per-user `read` ACL right — code `RightRequired`.\n  * `POST` / `PUT /user`: when a non-`system.root` requester lacks\n    the ACL right needed to create or modify a targeted user\n    (linking/unlinking groups, writing another user, or changing\n    an owner) — code `RightRequired`. Other save-right violations\n    (for example modifying a protected field of your own record)\n    are reported as `400`, not `403`.\n  * `DELETE /user/{id}`: when the requester holds neither\n    `system.user` nor `system.root` (`SystemRightRequired`); or\n    when a `system.user`-but-not-`system.root` requester lacks the\n    per-user `delete` ACL right on the target — code\n    `RightRequired`.\n  * `POST /user/change_password`: when the requester lacks the\n    `system.user.change_password` system right (or `system.root`) —\n    code `SystemRightRequired`; or when the new password fails the\n    configured complexity rules — code\n    `PasswordRequirementNotFulfilled` (the `error` message carries\n    the configured password hint).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/user/session": {
      "x-path": "/user",
      "description": "Report the current session. Returns the access token, the\nauthenticated user, their groups, system rights, the resolved\nconfiguration (defaults and base config) and the instance settings.\nRequires an authenticated session, no specific system right; a request\nwith no (or an invalid) token is answered with `400` `InvalidToken`.\n",
      "get": {
        "summary": "Information about the current session.",
        "description": "Returns the access token, the authenticated user, their groups,\nsystem rights, the resolved configuration (defaults and base config)\nand the instance settings. Does not require any specific system right\nbeyond being authenticated. Unlike the other `/user` operations, an\nunauthenticated request is rejected with `400` `InvalidToken` rather\nthan `401`.\n",
        "responses": {
          "200": {
            "description": "The current session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionApi"
                }
              }
            }
          },
          "400": {
            "description": "No authenticated user — the request carried no token or an\ninvalid one. The `code` is `InvalidToken`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/user/change_password": {
      "x-path": "/user",
      "description": "Change the authenticated user's own password. The current password\n(`password`) is re-confirmed and verified, the `new_password` must\nsatisfy the configured complexity rules, and on success the user's\nexisting OAuth2 tokens are invalidated. Requires the\n`system.user.change_password` system right (or `system.root`).\n\nDiffers from easydb 5: changing the password is here a `/user`\noperation; in easydb 5 it is `POST /api/v1/session/change_password`.\n",
      "post": {
        "summary": "Change the authenticated user's password.",
        "description": "Changes the **authenticated user's** password. The current password\n(`password`) must be supplied and is verified; it is always the\nauthenticated user's own password that is changed. Requires the\n`system.user.change_password` system right (or `system.root`). The new\npassword must satisfy the configured complexity rules. On success, the\nuser's existing OAuth2 tokens are invalidated.\n\nThe request body is form-encoded (`application/x-www-form-urlencoded`)\nor sent as a JSON object; the fields below are read with `FormValue`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "new_password": {
                    "type": "string",
                    "description": "The new password."
                  },
                  "password": {
                    "type": "string",
                    "description": "The current password, re-confirmed. Must be non-empty and\nmust match the authenticated user's current password.\n"
                  }
                },
                "required": [
                  "new_password",
                  "password"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    }
                  },
                  "example": {
                    "status": "ok"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the\nresponse identifies the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UserNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteSystemUserError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeleteSelfError"
                    },
                    {
                      "$ref": "#/components/schemas/UserLimitNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeletePolicyError"
                    },
                    {
                      "$ref": "#/components/schemas/UserArchivedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserPictureNoRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/UserTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UnableToSetPasswordForUserTypeError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnNeedsSystemRootError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnCanNotBeUpdatedError"
                    },
                    {
                      "$ref": "#/components/schemas/NoPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/WrongPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/PasswordChangedRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/UserEmailMalformedError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is not allowed to perform the operation.\nThe exact condition depends on the operation:\n\n  * `GET /user`: only when `include_password=true` and the\n    requester lacks `system.root` — code `SystemRightRequired`.\n  * `GET /user/{id}`: when `include_password=true` and the\n    requester lacks `system.root` (`SystemRightRequired`); or when\n    a non-`system.root` requester neither owns the target user nor\n    holds the per-user `read` ACL right — code `RightRequired`.\n  * `POST` / `PUT /user`: when a non-`system.root` requester lacks\n    the ACL right needed to create or modify a targeted user\n    (linking/unlinking groups, writing another user, or changing\n    an owner) — code `RightRequired`. Other save-right violations\n    (for example modifying a protected field of your own record)\n    are reported as `400`, not `403`.\n  * `DELETE /user/{id}`: when the requester holds neither\n    `system.user` nor `system.root` (`SystemRightRequired`); or\n    when a `system.user`-but-not-`system.root` requester lacks the\n    per-user `delete` ACL right on the target — code\n    `RightRequired`.\n  * `POST /user/change_password`: when the requester lacks the\n    `system.user.change_password` system right (or `system.root`) —\n    code `SystemRightRequired`; or when the new password fails the\n    configured complexity rules — code\n    `PasswordRequirementNotFulfilled` (the `error` message carries\n    the configured password hint).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/user/{id}": {
      "x-path": "/user",
      "description": "Read or remove a single user identified by `id` (their `_id`). `GET`\nreturns the user as an array with one element (an unknown well-formed\nid yields `400` `UserNotFound`, not `404`); `DELETE` deletes, archives\nor restores the user according to `delete_policy`.\n",
      "get": {
        "summary": "Retrieve a single user by id.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The user's `_id`."
          },
          {
            "name": "include_password",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If `true`, the response includes the stored password hash (for\nbackup tooling). Requires `system.root`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The user, returned as an array with a single element. When the id\nis well-formed but no user exists, the response is `400` with code\n`UserNotFound` (not `404`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UserApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the\nresponse identifies the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UserNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteSystemUserError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeleteSelfError"
                    },
                    {
                      "$ref": "#/components/schemas/UserLimitNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeletePolicyError"
                    },
                    {
                      "$ref": "#/components/schemas/UserArchivedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserPictureNoRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/UserTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UnableToSetPasswordForUserTypeError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnNeedsSystemRootError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnCanNotBeUpdatedError"
                    },
                    {
                      "$ref": "#/components/schemas/NoPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/WrongPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/PasswordChangedRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/UserEmailMalformedError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is not allowed to perform the operation.\nThe exact condition depends on the operation:\n\n  * `GET /user`: only when `include_password=true` and the\n    requester lacks `system.root` — code `SystemRightRequired`.\n  * `GET /user/{id}`: when `include_password=true` and the\n    requester lacks `system.root` (`SystemRightRequired`); or when\n    a non-`system.root` requester neither owns the target user nor\n    holds the per-user `read` ACL right — code `RightRequired`.\n  * `POST` / `PUT /user`: when a non-`system.root` requester lacks\n    the ACL right needed to create or modify a targeted user\n    (linking/unlinking groups, writing another user, or changing\n    an owner) — code `RightRequired`. Other save-right violations\n    (for example modifying a protected field of your own record)\n    are reported as `400`, not `403`.\n  * `DELETE /user/{id}`: when the requester holds neither\n    `system.user` nor `system.root` (`SystemRightRequired`); or\n    when a `system.user`-but-not-`system.root` requester lacks the\n    per-user `delete` ACL right on the target — code\n    `RightRequired`.\n  * `POST /user/change_password`: when the requester lacks the\n    `system.user.change_password` system right (or `system.root`) —\n    code `SystemRightRequired`; or when the new password fails the\n    configured complexity rules — code\n    `PasswordRequirementNotFulfilled` (the `error` message carries\n    the configured password hint).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a user by id.",
        "description": "Removes a user. System users (`system:root`, `system:everybody`, ...)\ncannot be deleted, and the requester cannot delete themselves. The\nbehaviour is selected by `delete_policy`:\n\n  * `delete` — hard-deletes the user record. Objects, pools, groups and\n    share links owned by the user are reassigned to the system user\n    `system:deleted_user`. Irreversible.\n  * `archive` — sets `_archived_at` and pseudonymizes the user record\n    (name, address, login and email are cleared or randomized per the\n    group's pseudonymization configuration). The user's collections are\n    deleted and cannot be restored. Irreversible.\n  * `unarchive` — restores a previously archived user.\n\nWhen `delete_policy` is omitted, the instance's configured default\npolicy applies; if that is `ask` (or the selection is ambiguous), the\nendpoint returns a `202` prompting the caller to choose (see below).\nThe deleted, archived or restored user record(s) are returned.\n\nDiffers from easydb 5: the caller chooses the outcome explicitly via\n`delete_policy` (`delete`, `archive` or `unarchive`), and an omitted\npolicy can yield a `202` prompt. In easydb 5 there is no such\nparameter — the user \"is _archived_ if there has been activity,\notherwise deleted\", and there is no unarchive via this endpoint.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The user's `_id`."
          },
          {
            "name": "delete_policy",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "delete",
                "archive",
                "unarchive"
              ]
            },
            "description": "How to remove the user. Omit to receive a `202` prompting for the\nchoice (when the configured default policy is `ask`). See the\noperation description for the semantics of each value.\n"
          },
          {
            "name": "confirm",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Carried by the `202` confirm button. The operative parameter when\nresolving the `202` is `delete_policy`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The affected user record(s), as an array of `UserApi`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UserApi"
                  }
                }
              }
            }
          },
          "202": {
            "description": "No `delete_policy` was supplied (and the default is `ask`). The body\nlists the allowed policies; re-send with the chosen `delete_policy`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDelete202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the\nresponse identifies the specific reason.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UserNotFoundError"
                    },
                    {
                      "$ref": "#/components/schemas/DeleteSystemUserError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeleteSelfError"
                    },
                    {
                      "$ref": "#/components/schemas/UserLimitNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserDeletePolicyError"
                    },
                    {
                      "$ref": "#/components/schemas/UserArchivedError"
                    },
                    {
                      "$ref": "#/components/schemas/UserPictureNoRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/UserTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/UnableToSetPasswordForUserTypeError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnNeedsSystemRootError"
                    },
                    {
                      "$ref": "#/components/schemas/ColumnCanNotBeUpdatedError"
                    },
                    {
                      "$ref": "#/components/schemas/NoPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/WrongPasswordError"
                    },
                    {
                      "$ref": "#/components/schemas/PasswordChangedRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/UserEmailMalformedError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is not allowed to perform the operation.\nThe exact condition depends on the operation:\n\n  * `GET /user`: only when `include_password=true` and the\n    requester lacks `system.root` — code `SystemRightRequired`.\n  * `GET /user/{id}`: when `include_password=true` and the\n    requester lacks `system.root` (`SystemRightRequired`); or when\n    a non-`system.root` requester neither owns the target user nor\n    holds the per-user `read` ACL right — code `RightRequired`.\n  * `POST` / `PUT /user`: when a non-`system.root` requester lacks\n    the ACL right needed to create or modify a targeted user\n    (linking/unlinking groups, writing another user, or changing\n    an owner) — code `RightRequired`. Other save-right violations\n    (for example modifying a protected field of your own record)\n    are reported as `400`, not `403`.\n  * `DELETE /user/{id}`: when the requester holds neither\n    `system.user` nor `system.root` (`SystemRightRequired`); or\n    when a `system.user`-but-not-`system.root` requester lacks the\n    per-user `delete` ACL right on the target — code\n    `RightRequired`.\n  * `POST /user/change_password`: when the requester lacks the\n    `system.user.change_password` system right (or `system.root`) —\n    code `SystemRightRequired`; or when the new password fails the\n    configured complexity rules — code\n    `PasswordRequirementNotFulfilled` (the `error` message carries\n    the configured password hint).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/right": {
      "description": "Access the ACL definitions and the per-context **right presets**\nused elsewhere in the API (collections, objects, pools, ...).\n",
      "get": {
        "summary": "List all right definitions known to this fylr instance.",
        "description": "Returns the `Rights` document: the right catalog built from the\nbuilt-in `rights.yml`, plus the `system` rights contributed by\nenabled plugins (named `plugin.\u003cplugin\u003e.\u003cright\u003e`), plus every saved\n`object` and `collection` preset. The document is the same for any\nauthenticated user — it is not filtered per session.\n\nDiffers from easydb 5: there is no per-`context` filter on this\nendpoint. easydb 5 documents `GET /api/v1/right[/\u003ccontext\u003e]` where\nthe list can optionally be filtered by context; fylr serves only\n`GET /right` and always returns the full catalog.\n",
        "responses": {
          "200": {
            "description": "The right catalog.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RightsCatalog"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/right/{context}/presets": {
      "x-path": "/right",
      "description": "List the right presets defined for a `context` (`object` or\n`collection`), or save presets for it. Each preset in the request\nis created when its `_version` is `1` and updated when its `_version`\nis greater than `1`.\n",
      "post": {
        "summary": "Create or update right presets for a context.",
        "description": "Saves one or more presets. A preset whose `_version` is `1` is\ninserted (a new `_id` is assigned if none was sent); a preset whose\n`_version` is greater than `1` updates the existing preset with that\n`_id`, and the sent `_version` must equal the stored `_version` plus\none (otherwise the request fails with 400 `VersionMismatch`). The\nresponse carries the saved presets.\n\nSupported `context` values are `object` and `collection`. Any other\ncontext value is rejected with status 400 (a generic `ServerGeneric`\nerror).\n\nRequires the `system.rightpresetmanager` right. Rejected with 400\n(`ReadOnlyMode`) when the instance is in read-only mode.\n\nDiffers from easydb 5: saving presets can return a 202 confirmation\nstep driven by the post-save collection-ACL re-validation (re-send\nwith `allow_invalid_acl=true` or `background_invalid_acl=true`).\neasydb 5 documents only 200/400/500 for this save and no\nconfirmation flow.\n",
        "parameters": [
          {
            "name": "context",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "object",
                "collection"
              ]
            },
            "description": "The context the presets apply to."
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "When true, the post-save collection-ACL validity check does not\nraise an error if applying the presets would leave some\ncollections with an invalid ACL; the save still persists.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "When true, the collection-ACL re-validation is queued as a\nbackground task instead of running synchronously, and the request\nreturns immediately. This is the value the 202 confirmation\nbutton re-sends.\n"
          },
          {
            "name": "background_invalid_acl_timelimit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Go duration (for example `30s`) overriding the synchronous time\nlimit for the collection-ACL re-validation before a 202 is\noffered. The default limit is `30s`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PresetApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The presets were saved.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PresetApi"
                  }
                }
              }
            }
          },
          "202": {
            "description": "The post-save collection-ACL re-validation needs confirmation\nbefore the transaction can commit. Two cases raise this:\n\n- the re-validation exceeded the synchronous time limit — re-send\n  the same `POST` with `background_invalid_acl=true` to run it as\n  a background task; or\n- applying the presets would leave a collection with an invalid\n  ACL and the session user may store that collection's ACL —\n  re-send with `allow_invalid_acl=true` to persist the save and\n  mark the affected collections invalid.\n\nThe 202 body carries the button that re-sends the matching\nparameter.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RightPresetPost202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed (invalid payload, unknown\ncontext, ACL validation failure). The right-check pipeline\nrejects presets that reference unknown rights (code\n`UnknownRight`), unknown right parameters (`UnknownRightParam`),\nunaccepted parameter values (`UnknownRightValue`), or non-unique\nchoices (`ChoiceNotUnique`). An unknown `context` is rejected\nwith code `ServerGeneric`; a read-only instance with code\n`ReadOnlyMode`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UnknownRightError"
                    },
                    {
                      "$ref": "#/components/schemas/UnknownRightParamError"
                    },
                    {
                      "$ref": "#/components/schemas/UnknownRightValueError"
                    },
                    {
                      "$ref": "#/components/schemas/ChoiceNotUniqueError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks `system.rightpresetmanager`\n(required for the preset save and delete operations).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List right presets for a context.",
        "parameters": [
          {
            "name": "context",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "object",
                "collection"
              ]
            },
            "description": "The context to list presets for."
          }
        ],
        "responses": {
          "200": {
            "description": "Array of presets.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PresetApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "400": {
            "description": "The `context` path segment is neither `object` nor `collection`\n(code `UnknownEndpointMethod`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnknownEndpointMethodError"
                }
              }
            }
          }
        }
      }
    },
    "/right/{context}/presets/{presetId}": {
      "x-path": "/right",
      "description": "Retrieve or delete a single right preset, identified by its `_id`\nwithin a `context` (`object` or `collection`). A delete of a preset\nstill referenced by any right row returns 202 until re-sent with\n`confirm=delete`.\n",
      "get": {
        "summary": "Retrieve a single right preset.",
        "description": "The matching preset is returned wrapped in a one-element array — the\nresponse is always an array. An unknown `presetId` yields an empty\narray `[]` with status 200, not a 404.\n",
        "parameters": [
          {
            "name": "context",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "object",
                "collection"
              ]
            },
            "description": "The context the preset applies to."
          },
          {
            "name": "presetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The preset's `_id`."
          }
        ],
        "responses": {
          "200": {
            "description": "The matching preset wrapped in a one-element array, or an empty\narray if no preset matches the id in this `context`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PresetApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "400": {
            "description": "The `context` path segment is neither `object` nor `collection`\n(code `UnknownEndpointMethod`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnknownEndpointMethodError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a right preset.",
        "description": "Deletes the preset with the given `_id`. Deleting an unknown\n`presetId` is a no-op that still returns 200. If the preset is still\nreferenced by any `right` row that is either not tied to a specific\nobject or tied to a current (latest, non-deleted) object, the first\nrequest returns 202 instead of deleting; re-send with\n`confirm=delete` to confirm. On confirm the preset is removed and the\ndatabase cascade deletes every `right` row that references it\n(including rows on archived object versions).\n\nRequires the `system.rightpresetmanager` right. Rejected with 400\n(`ReadOnlyMode`) when the instance is in read-only mode.\n\nDiffers from easydb 5: deleting a referenced preset returns a 202\nconfirmation step (re-send with `confirm=delete`) instead of\ndeleting outright. easydb 5 documents only 200/400/500 for this\ndelete and no confirmation flow.\n",
        "parameters": [
          {
            "name": "context",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "object",
                "collection"
              ]
            }
          },
          {
            "name": "presetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          },
          {
            "name": "confirm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "delete"
              ]
            },
            "description": "Set `confirm=delete` to confirm deletion of a preset that is\nstill referenced by a right row; without it such a delete returns\n202 instead of deleting. The 202's button re-sends this parameter.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The preset was deleted. Deleting an unknown `presetId` also\nreturns this acknowledgement.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The preset is still referenced by a `right` row that is either\nnot tied to a specific object or tied to a current (latest,\nnon-deleted) object. Re-send the same `DELETE` with\n`confirm=delete` to delete the preset; the database cascade then\nremoves every `right` row that references it (including rows on\narchived object versions).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RightPresetDelete202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. A read-only instance rejects\nthe delete with code `ReadOnlyMode`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadOnlyModeError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks `system.rightpresetmanager`\n(required for the preset save and delete operations).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/pool": {
      "description": "Manage **pools** — fylr's hierarchical containers for storage,\npermissions and metadata defaults. Pools form a tree; each pool can\ninherit ACL items and configuration from its parent.\n\nDiffers from easydb 5: a save that touches collection ACLs is\nconfirmed with the `allow_invalid_acl` / `background_invalid_acl` /\n`background_invalid_acl_timelimit` query parameters instead of\neasydb 5's single `collection_rights_policy` parameter.\n\nDiffers from easydb 5: there is no separate `system.rights_management`\nright for updating rights-management attributes on the root pool —\nevery save is gated on `system.poolmanager` (or `system.root`) plus\nthe per-pool `bag_*` rights. (easydb 5 required `system.rights_management`\nfor root-pool rights changes.)\n",
      "post": {
        "summary": "Create or update one or more pools.",
        "parameters": [
          {
            "name": "confirm",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "resync",
                "skip"
              ]
            },
            "description": "Answer to the file-resync 202 prompt. When a save changes a\npool's watermark or caption, the originals in that pool must\nbe re-rendered. Resend with `confirm=resync` to schedule the\nre-sync, or `confirm=skip` to save without re-rendering.\nOmitting it on the first request triggers the 202 prompt.\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "After the pool change, **fylr** re-checks the ACL validity of\ncollections affected by the pool's ACL. With\n`allow_invalid_acl=true` the save is accepted even if some\ncollections end up with an invalid ACL; with the default\n`false` such a case is returned as an error.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "If `true`, the post-save collection-ACL re-check is queued as\na background task instead of running inline, and the request\nreturns without waiting for it.\n"
          },
          {
            "name": "background_invalid_acl_timelimit",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Go duration string (e.g. `30s`) bounding the inline\ncollection-ACL re-check. Defaults to `30s`. If the check\nexceeds it, the response is a 202 offering to continue the\ncheck in the background (`background_invalid_acl=true`).\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PoolApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The pools were saved.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PoolApi"
                  }
                }
              }
            }
          },
          "202": {
            "description": "A confirmation is required before the save can complete. Two\ncases: (a) a watermark or caption change needs originals to be\nre-rendered — resend with `confirm=resync` or `confirm=skip`;\n(b) the post-save collection-ACL re-check exceeded its time\nlimit — resend with `background_invalid_acl=true` to finish it\nin the background.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PoolPost202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Triggers include an\ninvalid payload, the instance being in read-only mode (code\n`ReadOnlyMode`), a save of a non-root pool without a parent\n(code `PoolNeedsParent`), and — on `DELETE` — a pool that\nstill holds objects (code `PoolNotEmpty`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/PoolNeedsParentError"
                    },
                    {
                      "$ref": "#/components/schemas/PoolNotEmptyError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The request is forbidden. For POST/PUT, DELETE and `/stats`\nthe user must hold the `system.poolmanager` system right (or\n`system.root`); otherwise the response is code\n`SystemRightRequired` with `parameters.rights` naming the\nrequired right(s). For reads (`GET /pool/{poolID}`, `/stats`)\nand the per-pool BAG checks on save and delete, the relevant\npool `_acl` grant is missing (code `RightRequired`, with\n`parameters.right` naming the missing right, e.g. `bag_read`,\n`bag_create`, `bag_write`, `bag_acl`, `bag_delete`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create or update one or more pools (alias for POST).",
        "parameters": [
          {
            "name": "confirm",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "resync",
                "skip"
              ]
            },
            "description": "Answer to the file-resync 202 prompt. When a save changes a\npool's watermark or caption, the originals in that pool must\nbe re-rendered. Resend with `confirm=resync` to schedule the\nre-sync, or `confirm=skip` to save without re-rendering.\nOmitting it on the first request triggers the 202 prompt.\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "After the pool change, **fylr** re-checks the ACL validity of\ncollections affected by the pool's ACL. With\n`allow_invalid_acl=true` the save is accepted even if some\ncollections end up with an invalid ACL; with the default\n`false` such a case is returned as an error.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "If `true`, the post-save collection-ACL re-check is queued as\na background task instead of running inline, and the request\nreturns without waiting for it.\n"
          },
          {
            "name": "background_invalid_acl_timelimit",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Go duration string (e.g. `30s`) bounding the inline\ncollection-ACL re-check. Defaults to `30s`. If the check\nexceeds it, the response is a 202 offering to continue the\ncheck in the background (`background_invalid_acl=true`).\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PoolApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The pools were saved.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PoolApi"
                  }
                }
              }
            }
          },
          "202": {
            "description": "A confirmation is required before the save can complete. Two\ncases: (a) a watermark or caption change needs originals to be\nre-rendered — resend with `confirm=resync` or `confirm=skip`;\n(b) the post-save collection-ACL re-check exceeded its time\nlimit — resend with `background_invalid_acl=true` to finish it\nin the background.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PoolPost202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Triggers include an\ninvalid payload, the instance being in read-only mode (code\n`ReadOnlyMode`), a save of a non-root pool without a parent\n(code `PoolNeedsParent`), and — on `DELETE` — a pool that\nstill holds objects (code `PoolNotEmpty`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/PoolNeedsParentError"
                    },
                    {
                      "$ref": "#/components/schemas/PoolNotEmptyError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The request is forbidden. For POST/PUT, DELETE and `/stats`\nthe user must hold the `system.poolmanager` system right (or\n`system.root`); otherwise the response is code\n`SystemRightRequired` with `parameters.rights` naming the\nrequired right(s). For reads (`GET /pool/{poolID}`, `/stats`)\nand the per-pool BAG checks on save and delete, the relevant\npool `_acl` grant is missing (code `RightRequired`, with\n`parameters.right` naming the missing right, e.g. `bag_read`,\n`bag_create`, `bag_write`, `bag_acl`, `bag_delete`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List all pools visible to the authenticated user.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "default": 1000
            },
            "description": "Maximum number of pools to return. Defaults to `1000`. The\nserver pages internally and returns at most `limit` pools the\nsession is allowed to read.\n"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of pools to skip before collecting results. Defaults to\n`0`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Array of all pools the current session can see.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PoolApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/pool/{poolID}": {
      "x-path": "/pool",
      "description": "Read or delete a single **pool** identified by `poolID`. `GET`\nreturns the pool, wrapped in a single-element array (requires the\n`bag_read` right on it); `DELETE` removes it (requires the\n`system.poolmanager` system right and `bag_delete`, and only\nsucceeds when the pool and its subpools hold no objects).\n\nDiffers from easydb 5: on `GET`, the ACL block and the other\nadministrative fields are included only when the session holds the\n`system.poolmanager` system right (or `system.root`), not based on\nthe per-pool `bag_write` right. (easydb 5 includes the ACL when the\nuser has `bag_write` and omits it when the user has only `bag_read`.)\n",
      "get": {
        "summary": "Retrieve a single pool by id.",
        "parameters": [
          {
            "name": "poolID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The pool's `_id`."
          }
        ],
        "responses": {
          "200": {
            "description": "A single-element array containing the requested pool. The\nhandler always serialises the pool list as a JSON array, even\nfor one pool.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PoolApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The request is forbidden. For POST/PUT, DELETE and `/stats`\nthe user must hold the `system.poolmanager` system right (or\n`system.root`); otherwise the response is code\n`SystemRightRequired` with `parameters.rights` naming the\nrequired right(s). For reads (`GET /pool/{poolID}`, `/stats`)\nand the per-pool BAG checks on save and delete, the relevant\npool `_acl` grant is missing (code `RightRequired`, with\n`parameters.right` naming the missing right, e.g. `bag_read`,\n`bag_create`, `bag_write`, `bag_acl`, `bag_delete`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a pool by id.",
        "description": "Deletes the pool. The session must hold the `system.poolmanager`\nsystem right and the `bag_delete` right on the pool. Pools that\nstill contain objects (directly or via subpools) cannot be deleted\n— the response surfaces this as a 400 with code `PoolNotEmpty`.\n\nDiffers from easydb 5: an unknown pool id is reported as `404`\nwith code `ResourceNotFound`. (easydb 5 returns a `400` \"pool id\nnot found\" error.)\n",
        "parameters": [
          {
            "name": "poolID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The pool's `_id`."
          }
        ],
        "responses": {
          "200": {
            "description": "The pool was deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Triggers include an\ninvalid payload, the instance being in read-only mode (code\n`ReadOnlyMode`), a save of a non-root pool without a parent\n(code `PoolNeedsParent`), and — on `DELETE` — a pool that\nstill holds objects (code `PoolNotEmpty`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/PoolNeedsParentError"
                    },
                    {
                      "$ref": "#/components/schemas/PoolNotEmptyError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The request is forbidden. For POST/PUT, DELETE and `/stats`\nthe user must hold the `system.poolmanager` system right (or\n`system.root`); otherwise the response is code\n`SystemRightRequired` with `parameters.rights` naming the\nrequired right(s). For reads (`GET /pool/{poolID}`, `/stats`)\nand the per-pool BAG checks on save and delete, the relevant\npool `_acl` grant is missing (code `RightRequired`, with\n`parameters.right` naming the missing right, e.g. `bag_read`,\n`bag_create`, `bag_write`, `bag_acl`, `bag_delete`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The pool id in the URL does not match any stored pool. The\nresponse carries `code: ResourceNotFound` with\n`parameters.resource` = `Pool \u003cid\u003e`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/pool/{poolID}/stats": {
      "x-path": "/pool",
      "description": "Asset statistics for the **pool** identified by `poolID` — file\ncounts and storage sizes of originals (latest, history and deleted),\nreturned as a `PoolStats` object. Requires the `system.poolmanager`\nsystem right and `bag_read` on the pool; `include_subpools=true`\nrolls the figures up over the pool's sub-tree.\n",
      "get": {
        "summary": "Statistics for a single pool.",
        "description": "Returns file/asset statistics (counts and storage sizes of\noriginals — latest, history and deleted) for the pool. Requires\nthe `system.poolmanager` system right and `bag_read` on the pool.\nWith `include_subpools=true` the figures roll up the whole\nsub-tree below the pool; otherwise only this pool.\n",
        "parameters": [
          {
            "name": "poolID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The pool's `_id`."
          },
          {
            "name": "include_subpools",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "If `true`, the counts roll up the whole sub-tree below the\nrequested pool. Defaults to `false`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Asset statistics for the pool — file counts and storage\nusage scoped to this pool (and, with `include_subpools=true`,\nits transitive sub-tree).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PoolStats"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The request is forbidden. For POST/PUT, DELETE and `/stats`\nthe user must hold the `system.poolmanager` system right (or\n`system.root`); otherwise the response is code\n`SystemRightRequired` with `parameters.rights` naming the\nrequired right(s). For reads (`GET /pool/{poolID}`, `/stats`)\nand the per-pool BAG checks on save and delete, the relevant\npool `_acl` grant is missing (code `RightRequired`, with\n`parameters.right` naming the missing right, e.g. `bag_read`,\n`bag_create`, `bag_write`, `bag_acl`, `bag_delete`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/RightRequiredError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/objecttype": {
      "description": "Read and write **objecttypes** — the per-record-type configuration\nthat fylr layers on the datamodel definition (default masks, exposure\nflags, ACL, tags, transitions, mask / column filters, asset-filename\npolicy, watermark and janitor policy). The objecttype itself (its name, fields and\nhierarchy) is part of the datamodel and is created through the schema\nendpoints; this endpoint only configures objecttypes that already\nexist in the current (committed) datamodel. A write updates the\nobjecttype configuration directly and takes effect immediately when\nthe request transaction commits — there is no working copy and no\nseparate `schema/commit` step.\n\n`GET` is open to any authenticated user; `POST` requires\n`system.objecttypemanager`. Authentication is by access token (a\n`Bearer` header or the `access_token` query parameter).\n\nDiffers from easydb 5: writes that touch collection ACLs are\nconfirmed with the `confirm` / `allow_invalid_acl` /\n`background_invalid_acl` query parameters instead of easydb 5's\nsingle `collection_rights_policy` parameter.\n",
      "get": {
        "summary": "List all objecttypes in the current datamodel.",
        "description": "Returns every objecttype in the current datamodel as an\narray of descriptors. Any authenticated user may read; the\nauxiliary fields that need `system.objecttypemanager` are included\nonly when that right is held (or are dropped entirely with\n`format=short`).\n",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "short"
              ]
            },
            "description": "Set `format=short` to omit the auxiliary fields that require\nthe `system.objecttypemanager` right (`_acl`, tags,\ntransitions, mask / column filters, etc.). Any other value,\nor omitting the parameter, returns the full descriptor. Only\n`short` is special-cased — there is no separate `long` /\n`standard` behaviour.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Array of objecttype descriptors.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ObjecttypeApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create or update the settings of one or more objecttypes.",
        "description": "Updates the configuration of an array of objecttypes directly. The\nobjecttypes must already exist in the committed datamodel; this\nendpoint writes their settings, not their structure. The change\ntakes effect immediately when the request transaction commits —\nthere is no `schema/commit` step. The user needs\n`system.objecttypemanager` (or `system.root`). When the instance is\nin read-only mode the request is rejected before processing (see\nthe 400 response).\n\nThe objecttype itself (its name, fields, hierarchy) is defined by\nthe datamodel, not created here — every element must carry an\nexisting `objecttype._id`, and `objecttype._version` must be\n`current + 1` (optimistic locking; a mismatch is a 400\n`VersionMismatch`). Only the configuration fields are mutated;\nfields the requester is not allowed to change are ignored. Fields\nomitted from the body keep their stored value (the server reloads\nthe current objecttype and merges). Notable parse rules:\n\n  * `mapping_*` fields take a mapping id or the string `\"none\"` to\n    clear; `mapping_image_import_recipe_configs` may only be set\n    when `mapping_image_import` names a real mapping.\n  * `_standard_masks`: `null` clears the preference; a non-empty\n    array of mask ids sets it; an empty array `[]` is rejected\n    (`ObjecttypeNeedsStandardMask`).\n  * `watermark.gravity`, if present, must be one of `nw n ne w c e\n    sw s se` or empty.\n  * `caption` keys must each name an existing files field that is\n    not inside a reverse-nested and whose objecttype's pool\n    management matches the endpoint (objecttype, not pool).\n  * `janitor_policy` bounds must be `null` or `\u003e= 0`. `janitor_policy`\n    is only meaningful for non-pool objecttypes; for a pool\n    objecttype it is neither stored nor returned. The key is\n    merged from the stored value only when omitted — sending\n    `null` explicitly clears it.\n  * `standard_numbering` is accepted for compatibility but ignored\n    (never stored, always returned empty).\n\nThe save can pause and return a 202 to ask for confirmation (see\nthe 202 response). The query parameters below are how the client\nanswers those confirmations: it re-sends the **same** request body\nwith the matching parameter appended.\n\nDiffers from easydb 5: the 202 confirmation contract uses\n`confirm` / `allow_invalid_acl` / `background_invalid_acl` rather\nthan easydb 5's `collection_rights_policy`.\n",
        "parameters": [
          {
            "name": "confirm",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "resync",
                "skip"
              ]
            },
            "description": "Answer to the renditions-resync 202 that is raised when a\nwatermark or caption change requires recomputing the\nrenditions of already-stored files. `resync` recomputes them\nnow; `skip` saves without recomputing. Any other value is\nrejected with a generic 400 (`confirm \"\u003cvalue\u003e\" not\nsupported`).\n"
          },
          {
            "name": "allow_invalid_acl",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Answer to the invalid-collection-ACL 202. When `true`, a save\nwhose ACL change would invalidate a collection the owner can\nno longer fully grant is allowed to proceed; the affected\ncollections are flagged `invalid_acl` and sharing for them is\ndisabled. If the user lacks `bag-acl` on such a collection the\nrequest instead fails with `UrlParameterNotSupported` for\n`allow_invalid_acl`.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Answer to the ACL-revalidation timeout 202. When `true`, the\ncollection-ACL revalidation runs as an asynchronous background\ntask and the request returns immediately instead of completing\nthe check synchronously.\n"
          },
          {
            "name": "background_invalid_acl_timelimit",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Overrides the synchronous time budget before the timeout 202\nis offered. A Go duration string (e.g. `5s`); an invalid value\nsurfaces as a generic 400.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ObjecttypeApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The objecttypes were saved. The body echoes the saved\ndescriptors (with `_acl`, tags, transitions and mask filters\nincluded). The `X-Fylr-Cache-ID` response header carries the\nnew datamodel cache id so clients can invalidate caches.\n",
            "headers": {
              "X-Fylr-Cache-ID": {
                "schema": {
                  "type": "string"
                },
                "description": "Updated cache id (`\u003cstartup-unix\u003e-\u003ccache-id\u003e`), bumped on\nevery successful write.\n"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ObjecttypeApi"
                  }
                }
              }
            }
          },
          "202": {
            "description": "The save needs confirmation before it can complete. Resubmit\nthe identical request with the query parameter named by the\ntask's form option or button appended — for example\n`allow_invalid_acl=true`, `background_invalid_acl=true`, or\n`confirm=resync` / `confirm=skip`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjecttypePost202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. All errors below are\n`realm: api`, `statuscode: 400`. The objecttype-specific codes\n(`package: objecttype`) are `UnknownField` /\n`UnsupportedFieldType`, both raised while resolving an\n`_export_asset_filenames` template against the datamodel.\n\nThe body parse and the `ApiToObject` validation add several\n`package: ferrors` codes:\n\n  * `ReadOnlyMode` — the instance is in read-only mode; the\n    request is rejected before any processing (message\n    `Read-only mode is enabled.`).\n  * `VersionMismatch` — a submitted objecttype's `_version` is\n    not `current + 1`. `parameters.got` / `parameters.expected`\n    carry the values.\n  * `ObjecttypeNeedsStandardMask` — `_standard_masks` was sent\n    as an empty array (`[]`); send `null` to clear the\n    preference instead. `parameters.name` carries the\n    objecttype name.\n  * `UrlParameterNotSupported` — `allow_invalid_acl=true` was\n    sent but the user lacks `bag-acl` on an affected\n    collection. `parameters.param` is `allow_invalid_acl`.\n\nGeneric 400s (`code: ServerGeneric` or a bare message) also\nsurface here for: an unsupported `confirm` value (`confirm\n\"\u003cvalue\u003e\" not supported`); an unknown `_standard_masks` /\n`_maskfilters` mask id (`Objecttype: Mask \u003cid\u003e not found in\nDatamodel`); a `watermark.gravity` outside the allowed set\n(`watermark.gravity \"\u003cvalue\u003e\" not supported`); an out-of-range\n`janitor_policy` bound (a negative value;\n`janitor_policy.file_link_delete.keep_days_history_versions\nmust be null or \u003e 0` and the analogous `keep_count` /\n`min_object_deleted_days` messages); a bad `caption`\n(`caption \"\u003cfield\u003e\": field not found`, `... must not be inside\na reverse nested`, `... is not of type \"file\"`, or a\npool-management mismatch); recipe configs set while\n`mapping_image_import` is `\"none\"` (`mapping recipe configs can\nonly be set for a specific mapping`); own transitions / tags on\nan objecttype whose pool does not allow them (`Objecttype\n\"\u003cname\u003e\" cannot have own transitions` / `... own tags`); a bad\n`background_invalid_acl_timelimit` duration. Datamodel-validation,\nsave-pipeline and DB-driver errors (e.g.\n`DatabaseUniqueKeyViolation`) can appear too. The `code` enum\non the schema lists only the two objecttype codes; it is not\nexhaustive.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UnknownFieldError"
                    },
                    {
                      "$ref": "#/components/schemas/UnsupportedFieldTypeError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/VersionMismatchError"
                    },
                    {
                      "$ref": "#/components/schemas/ObjecttypeNeedsStandardMaskError"
                    },
                    {
                      "$ref": "#/components/schemas/UrlParameterNotSupportedError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/DatabaseUniqueKeyViolationError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (`system.objecttypemanager`, or `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "423": {
            "description": "The write could not acquire a database lock because a\nconcurrent write is touching the same rows (PostgreSQL\n`55P03`). The transaction is rolled back and the error is\nsurfaced as `code: DatabaseLockError`, `package: ferrors`,\n`statuscode: 423`. Retry the identical request once the\nconflicting write has finished.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatabaseLockError"
                }
              }
            }
          }
        }
      }
    },
    "/objecttype/{id}": {
      "x-path": "/objecttype",
      "description": "Read a single **objecttype** by its numeric `id`. Returns a\none-element array holding the descriptor; pass `format=short` to drop\nthe auxiliary fields that need the `system.objecttypemanager` right.\nAny authenticated user may read.\n\nDiffers from easydb 5: an unknown `id` returns a generic 400\n(`code: ServerGeneric`), not a 404.\n",
      "get": {
        "summary": "Retrieve a single objecttype.",
        "description": "Loads one objecttype by numeric `id` and returns it wrapped in a\none-element array (the descriptor is the only array entry — the\nresponse is not a bare object).\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            },
            "description": "The numeric id of the objecttype. The path segment must be a\npositive integer (route pattern `[1-9][0-9]*`); name-based\nlookup is not supported on this endpoint.\n"
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "short"
              ]
            },
            "description": "Set `format=short` to omit the auxiliary fields that require\nthe `system.objecttypemanager` right (`_acl`, tags,\ntransitions, mask / column filters, etc.). Any other value,\nor omitting the parameter, returns the full descriptor. Only\n`short` is special-cased — there is no separate `long` /\n`standard` behaviour.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "A one-element array containing the objecttype descriptor.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ObjecttypeApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The numeric `id` in the URL does not match any objecttype in\nthe current datamodel. The load fails and is reported as a\ngeneric server error (`code: ServerGeneric`, `package:\nferrors`, `statuscode: 400`) with a message of the form\n`Server error occurred: objecttype.LoadById: Error loading:\nObjecttypeList.Load: Not all objecttypes found in DB` — there\nis no structured 404 for an unknown id on this endpoint.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/objecttype/{id}/stats": {
      "x-path": "/objecttype",
      "description": "Read **asset statistics** for one objecttype, identified by its\nnumeric `id` — file counts and storage usage rolled up across every\nobject of the type. Requires the `system.objecttypemanager` right.\n\nfylr-only endpoint — easydb 5 has no `/objecttype/{id}/stats`\nequivalent.\n",
      "get": {
        "summary": "Asset statistics for an objecttype.",
        "description": "Aggregates, in SQL, the originals and their renditions across all\nlatest / history / deleted objects of the type, bucketing by file\nclass and extension. Requires the `system.objecttypemanager` right\n(or `system.root`).\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            },
            "description": "The numeric id of the objecttype (positive integer; route\npattern `[1-9][0-9]*`). Name-based lookup is not supported.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Asset statistics for the objecttype — file counts and\nstorage usage rolled up across every object of the type.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjecttypeStats"
                }
              }
            }
          },
          "400": {
            "description": "The numeric `id` in the URL does not match any objecttype in\nthe current datamodel. The load fails and is reported as a\ngeneric server error (`code: ServerGeneric`, `package:\nferrors`, `statuscode: 400`) with a message of the form\n`Server error occurred: objecttype.LoadById: Error loading:\nObjecttypeList.Load: Not all objecttypes found in DB` — there\nis no structured 404 for an unknown id on this endpoint.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for\nthe operation (`system.objecttypemanager`, or `system.root`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/mask/{version}": {
      "x-path": "/mask",
      "description": "Access the **mask** definitions of a datamodel version. Masks\nproject objecttypes to a subset of fields and are the unit through\nwhich the frontend renders forms and detail views. `version` can\nbe:\n\n  * `HEAD` — the working copy (uncommitted edits). Readable by any\n    authenticated user (`GET` requires only an authenticated user,\n    not `system.datamodel`).\n  * `CURRENT` — the most recently committed version. Resolved\n    server-side; equivalent to the highest committed number.\n  * a positive integer pointing at a specific committed version.\n",
      "get": {
        "summary": "Retrieve all masks for a datamodel version.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(HEAD|CURRENT|[1-9][0-9]*)$"
            },
            "description": "Datamodel version. `HEAD` returns the working copy (readable\nby any authenticated user); `CURRENT` resolves to the most\nrecently committed version; a numeric id resolves to a\nspecific committed version.\n"
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "standard",
                "long"
              ]
            },
            "description": "Output detail level. `standard` (default): field descriptors\nonly. `long`: additionally embeds each non-splitter field's\nunderlying `column` definition and `full_name`. Unrecognised\nvalues behave like `standard` (not rejected).\n\nDiffers from easydb 5: `format` selects the level of detail\nand the response is always JSON. easydb 5's `format` chose the\nserialization (`xml` — its default — or `json`); fylr has no\nXML output.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The mask-set for the requested datamodel version: a\n`MaskSchemaApi` wrapper (`type`, `version`,\n`based_on_schema_version`, `max_mask_id`) whose `masks` array\nholds one descriptor per mask.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MaskSchemaApi"
                }
              }
            }
          },
          "400": {
            "description": "The `version` segment is not a known committed version (or\n`HEAD` / `CURRENT`). Returns code `DatamodelVersionNotFound`,\npackage `datamodel`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatamodelVersionNotFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n\nDiffers from easydb 5: a missing/invalid session is reported\nas `401` (`UserRequired`); easydb 5 documents a single `403`\nfor both \"not authenticated\" and \"lacks required rights\".\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/mask/{version}/{mask}": {
      "x-path": "/mask",
      "description": "Read a single **mask** by name from a datamodel version. Returns the\nrequested mask wrapped in a `MaskSchemaApi` envelope. The reserved\nname `_all_fields` yields the objecttype's complete field set instead\nof a named mask. `version` accepts `HEAD`, `CURRENT`, or a committed\nversion number.\n",
      "get": {
        "summary": "Retrieve a single mask of a datamodel version.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(HEAD|CURRENT|[1-9][0-9]*)$"
            }
          },
          {
            "name": "mask",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Mask name. The special name `_all_fields` returns the\nobjecttype's complete field set (all columns), wrapped in the\nsame mask-set envelope. Available to any authenticated user.\n"
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "standard",
                "long"
              ]
            },
            "description": "Output detail level. `standard` (default): field descriptors\nonly. `long`: additionally embeds each non-splitter field's\nunderlying `column` definition and `full_name`. Unrecognised\nvalues behave like `standard` (not rejected).\n\nDiffers from easydb 5: `format` selects the level of detail\nand the response is always JSON. easydb 5's `format` chose the\nserialization (`xml` — its default — or `json`); fylr has no\nXML output.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "A `MaskSchemaApi` wrapper whose `masks` array contains the\nsingle requested mask (for `_all_fields`, the synthesised\nall-fields mask per objecttype).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MaskSchemaApi"
                }
              }
            }
          },
          "400": {
            "description": "The `version` segment is not a known committed version (or\n`HEAD` / `CURRENT`). Returns code `DatamodelVersionNotFound`,\npackage `datamodel`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatamodelVersionNotFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n\nDiffers from easydb 5: a missing/invalid session is reported\nas `401` (`UserRequired`); easydb 5 documents a single `403`\nfor both \"not authenticated\" and \"lacks required rights\".\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "The mask NAME in the URL does not exist for this datamodel\nversion (code `ResourceNotFound`, package `api`). An unknown\n`version` is reported as a 400 `DatamodelVersionNotFound`\n(package `datamodel`), not a 404.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/mask/HEAD": {
      "x-path": "/mask",
      "description": "Write the **mask** definitions into the working datamodel (`HEAD`).\nThe submitted `MaskSchemaApi` is stored as the uncommitted working\ncopy; the change becomes visible to other readers only after a\nseparate `POST /api/v1/schema/commit`. Requires\n`system.datamodel[level=development]` (or `[level=commit]`) and is\nrejected in read-only mode.\n",
      "post": {
        "summary": "Write masks into the working datamodel (`HEAD`).",
        "description": "Saves the supplied mask set into the working copy. The change is\nonly visible to other readers after a separate commit via\n`POST /api/v1/schema/commit`. Requires\n`system.datamodel[level=development]` (or `[level=commit]`).\nRejected in read-only mode.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MaskSchemaApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The HEAD masks were saved. Returns the complete stored HEAD\nmask-set (`MaskSchemaApi`, all masks — not just the submitted\nsubset) with any server-applied normalisation and the current\n`max_mask_id`. The response also carries an updated fylr\ncache-id header.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MaskSchemaApi"
                }
              }
            }
          },
          "400": {
            "description": "The submitted document is malformed or inconsistent with the\ncurrent objecttypes / fields (a datamodel-validator code such\nas `SchemaDuplicateMaskName`), OR the instance is in read-only\nmode (code `ReadOnlyMode`, package `ferrors`). Read-only\nrejections carry package `ferrors`, not `datamodel`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SchemaDuplicateMaskNameError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n\nDiffers from easydb 5: a missing/invalid session is reported\nas `401` (`UserRequired`); easydb 5 documents a single `403`\nfor both \"not authenticated\" and \"lacks required rights\".\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks `system.datamodel[level=development]`\n(or `[level=commit]`), the right required to write the HEAD\nmask-set. (`system.root` also satisfies the check.)\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/schema/user/{version}": {
      "x-path": "/schema",
      "description": "The **schema** endpoint exposes the JSON-Schema view of a datamodel\nversion — the structural description that `/api/db` and `/api/search`\nvalidate against. The same datamodel can also be rendered as a\ndiagram via `?format=svg` / `?format=png`.\n\n`version` can be:\n\n  * `HEAD` — the working copy (uncommitted edits).\n  * `CURRENT` — the most recently committed version. Resolved\n    server-side; equivalent to the highest committed number.\n  * a positive integer pointing at a specific committed version.\n\nReading requires only an authenticated user; no `system.datamodel`\nright is needed.\n",
      "get": {
        "summary": "Retrieve a datamodel snapshot.",
        "description": "Returns the datamodel either as a `SchemaApi` JSON object\n(default) or as an image of its objecttype graph.\n",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(HEAD|CURRENT|[1-9][0-9]*)$"
            },
            "description": "Datamodel version. `HEAD` returns the working copy;\n`CURRENT` resolves to the most recently committed version;\nnumeric ids return a specific committed snapshot.\n"
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "svg",
                "png"
              ]
            },
            "description": "When set, returns a rendered graph of the schema instead of\nthe JSON representation. The response is\n`image/svg+xml` / `image/png` with\n`Content-Disposition: inline; filename=\"fylr-schema-\u003cinstance\u003e-\u003cversion\u003e-v\u003cn\u003e.\u003cext\u003e\"`.\nAny other value (or no value) returns the JSON form.\n\nDiffers from easydb 5: the default (no `format`) response is the\nJSON `SchemaApi`, and there is no XML form. easydb 5 documented\n`format=xml` as the default representation.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The datamodel snapshot. By default a JSON `SchemaApi`\ndocument; when `format=svg` / `format=png`, the rendered\ngraph image.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaApi"
                }
              },
              "image/svg+xml": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "The objecttype graph rendered as SVG, returned when\n`format=svg`.\n"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "The objecttype graph rendered as PNG, returned when\n`format=png`.\n"
                }
              }
            }
          },
          "400": {
            "description": "The `version` in the URL does not resolve to an existing\ndatamodel — a numeric version that matches no datamodel row\n(the lookup is by version number, independent of whether that\nversion was committed), or a non-positive value. The body\ncarries code `DatamodelVersionNotFound`. Note this is a `400`,\nnot a `404`.\n\nDiffers from easydb 5: an unknown schema version is reported as\n`400` `DatamodelVersionNotFound`, not the `404` easydb 5\ndocumented for a \"Requested schema version not found\".\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatamodelVersionNotFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/schema/user/HEAD": {
      "x-path": "/schema",
      "description": "Writes the working datamodel (`HEAD`). A `POST` stores a\n`SchemaApi` document into the working copy and returns it back\n(normalised, with the bumped `max_table_id` / `max_column_id`).\nThe change stays invisible to plain readers until it is committed\nvia `POST /schema/commit`. Requires\n`system.datamodel[level=development]` or `[level=commit]`.\n",
      "post": {
        "summary": "Update the working datamodel (`HEAD`).",
        "description": "Writes the supplied `SchemaApi` document into the working copy.\nThe change is only visible to other readers after a commit via\n`POST /schema/commit`. Requires\n`system.datamodel[level=development]` (or `[level=commit]`).\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SchemaApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The HEAD datamodel was updated. The response returns the\nstored `SchemaApi` (with any server-applied normalisations\nand the bumped `max_table_id` / `max_column_id`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaApi"
                }
              }
            }
          },
          "400": {
            "description": "The submitted document is malformed or inconsistent with\nthe current objecttypes / masks: unknown column reference,\nduplicate names, a `max_table_id` / `max_column_id` smaller\nthan the stored value, or a `version` / `based_on_version`\nthat is not the expected next version. A column type change\nthat cannot be migrated because the column already holds data\nis rejected with code `TypeChangeUnsupported`. A deleted\nobjecttype that still holds objects is rejected with code\n`ObjecttypeNotEmpty` (`parameters.stats` names them). May also\nreturn code `ReadOnlyMode` when the instance is in read-only\nmode.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/TypeChangeUnsupportedError"
                    },
                    {
                      "$ref": "#/components/schemas/ObjecttypeNotEmptyError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user holds none of the system rights this\nwrite needs: `system.datamodel[level=development]`,\n`system.datamodel[level=commit]`, or `system.root`. The body\ncarries code `SystemRightRequired`; `parameters.rights` lists\nthe accepted rights.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/schema/commit": {
      "x-path": "/schema",
      "description": "Commits the working datamodel (`HEAD`), promoting it to a versioned\nsnapshot that readers without `system.datamodel` can see. A `POST`\nfreezes `HEAD`, sets its `committed_at`, and returns\n`{ \"status\": \"ok\" }`; the `reindex` and `confirm` query parameters\ngovern reindexing and the `202` confirm step. Requires\n`system.datamodel[level=commit]`.\n",
      "post": {
        "summary": "Commit the working datamodel (`HEAD`).",
        "description": "Promotes the working copy to a committed datamodel — sets its\n`committed_at` timestamp and makes its version visible to readers\nthat don't hold `system.datamodel`. HEAD already has a version\nnumber before the commit (it's the version a future commit would\nproduce); the commit just freezes it.\nRequires `system.datamodel[level=commit]` (or `system.root`).\n\nCommit options are query parameters:\n\n  * `reindex` — `skip` (no reindex), `reindex` (reindex in the\n    background), or `reindex_block` (reindex in the background\n    and temporarily lock the frontend). If a change needs a\n    reindex and `reindex` is absent, the call returns `202`\n    asking which to use.\n  * `confirm=yes` — acknowledge the `202` confirm task (reindex\n    and/or changed constraints) and proceed with the commit.\n\nThere is no destructive-change toggle: unsupported type changes\nare rejected with code `TypeChangeUnsupported`, not opted into.\n\nDiffers from easydb 5: reindexing is controlled by `reindex`\n(`skip` / `reindex` / `reindex_block`) plus a `202`/`confirm=yes`\nhandshake. easydb 5 had no such handshake and instead took a\n`reindex_generate_events=1` flag to emit `OBJECT_INDEX` events\nduring reindex jobs; fylr has no equivalent parameter here.\n",
        "parameters": [
          {
            "name": "reindex",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "skip",
                "reindex",
                "reindex_block"
              ]
            },
            "description": "Reindex behaviour for changes that need it. `skip` = none;\n`reindex` = background; `reindex_block` = background plus a\ntemporary frontend lock. Omit to be prompted via a `202`.\n"
          },
          {
            "name": "confirm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "yes"
              ]
            },
            "description": "Set to `yes` to acknowledge the `202` confirm task (reindex\nand/or changed constraints) and run the commit.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The commit succeeded. The response is a fixed\n`{ \"status\": \"ok\" }` object — the new version number is not\nin the body (read it via `GET /schema/user/CURRENT` or the\n`DATAMODEL_COMMIT` event).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ],
                      "description": "Always `ok` on success."
                    }
                  }
                },
                "example": {
                  "status": "ok"
                }
              }
            }
          },
          "202": {
            "description": "The commit needs confirmation before it runs. Returned when\nthe change requires a reindex and/or changes constraints and\nthe request did not already carry `confirm=yes`. Resend\n`POST /schema/commit?confirm=yes` (optionally with\n`reindex=skip` / `reindex` / `reindex_block`) to proceed.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaCommit202"
                }
              }
            }
          },
          "400": {
            "description": "The HEAD datamodel is inconsistent and cannot be committed: a\ncolumn type change that cannot be migrated because the column\nalready holds data is rejected with code\n`TypeChangeUnsupported`, and a deleted objecttype that still\nholds objects is rejected with code `ObjecttypeNotEmpty`\n(`parameters.stats` names them). May also return code\n`ReadOnlyMode` when the instance is in read-only mode.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/TypeChangeUnsupportedError"
                    },
                    {
                      "$ref": "#/components/schemas/ObjecttypeNotEmptyError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user holds neither\n`system.datamodel[level=commit]` nor `system.root`. The body\ncarries code `SystemRightRequired`; `parameters.rights` lists\nthe accepted rights.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/message": {
      "description": "Admin-managed **fylr** messages shown in the web front end, optionally\nrequiring per-user confirmation (`confirm_every_version`, `show_always`)\nand optionally scoped to a `start_time`/`end_time` window. A message is\naddressed to user groups via `_groups`, not to individual users. All\noperations require the `system.message` system right (or\n`system.root`); a user who holds it sees and manages every message —\nthere is no per-user sender/recipient scoping.\n\nDiffers from easydb 5: the message kind is the `webfrontend_type`\nfield (free-form) and the body text is `message`; easydb 5 named these\n`type` (with values such as `eula`) and `message_html`.\n",
      "post": {
        "summary": "Create or update one or more messages.",
        "description": "Each array element is upserted by `message._version`: send\n`_version: 1` to create a new message; send the stored version + 1\ntogether with `message._id` to update an existing one (a mismatch\nreturns `VersionMismatch`, 400). A save replaces the message's\n`_groups` set with the one supplied (an omitted/empty `_groups`\nclears it). Allowed in read-only mode.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MessageApi"
                },
                "example": [
                  {
                    "_basetype": "message",
                    "message": {
                      "webfrontend_props": {},
                      "webfrontend_type": null,
                      "confirm_every_version": true,
                      "title": {
                        "de-DE": "Testnachricht",
                        "en-US": ""
                      },
                      "reference": "Referenz!",
                      "message": {
                        "de-DE": "Testnachricht [DE]",
                        "en-US": "Testmessage  [US]"
                      },
                      "confirmation": {
                        "de-DE": "Bestätigung DE",
                        "en-US": "Confirm US"
                      },
                      "start_time": {
                        "value": "2019-01-09"
                      },
                      "end_time": {
                        "value": "2019-01-17"
                      },
                      "_version": 1
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The messages were created or updated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MessageApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Possible causes: an unparseable\nbody or other generic failure (`code: ServerGeneric`); an update\nwhose `_version` is not the stored version + 1 (`code:\nVersionMismatch`); a `start_time` after the `end_time` (`code:\nStartTimeAfterEndTime`); or a `_groups` entry referencing a group\n(by `reference`) that does not exist (`code: LookupNotFound`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/VersionMismatchError"
                    },
                    {
                      "$ref": "#/components/schemas/StartTimeAfterEndTimeError"
                    },
                    {
                      "$ref": "#/components/schemas/LookupNotFoundError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.message` system right\n(and is not `system.root`). The response carries\n`code: SystemRightRequired` (package `acl`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create or update one or more messages (alias for POST).",
        "description": "Identical to `POST /message`: the same handler decodes the body\nand upserts each element by `message._version`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MessageApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The messages were created or updated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MessageApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Possible causes: an unparseable\nbody or other generic failure (`code: ServerGeneric`); an update\nwhose `_version` is not the stored version + 1 (`code:\nVersionMismatch`); a `start_time` after the `end_time` (`code:\nStartTimeAfterEndTime`); or a `_groups` entry referencing a group\n(by `reference`) that does not exist (`code: LookupNotFound`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/VersionMismatchError"
                    },
                    {
                      "$ref": "#/components/schemas/StartTimeAfterEndTimeError"
                    },
                    {
                      "$ref": "#/components/schemas/LookupNotFoundError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.message` system right\n(and is not `system.root`). The response carries\n`code: SystemRightRequired` (package `acl`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List all messages.",
        "description": "Returns every stored message (no per-user filter), ordered by\n`_id` ascending. Requires the `system.message` system right.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 1000
            },
            "description": "Maximum number of messages to return. Results are ordered by\n`_id` ascending.\n"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 0
            },
            "description": "Number of leading messages to skip (for paging)."
          }
        ],
        "responses": {
          "200": {
            "description": "Array of messages.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MessageApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.message` system right\n(and is not `system.root`). The response carries\n`code: SystemRightRequired` (package `acl`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/message/{id}": {
      "x-path": "/message",
      "description": "Read or delete a single **fylr** message identified by its `_id`\n(a positive integer) in the URL. `GET` returns the message wrapped in a\none-element array; `DELETE` removes it and responds with\n`status.acknowledged: ok`. An `_id` that matches no stored message\nreturns `MessageNotFound` (404). Both operations require the\n`system.message` system right (or `system.root`); `DELETE` is allowed\nin read-only mode.\n",
      "get": {
        "summary": "Retrieve a single message by id.",
        "description": "Returns the matching message wrapped in a one-element array (the same\nhandler shape as the list endpoint), not a bare object.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The message's `_id`."
          }
        ],
        "responses": {
          "200": {
            "description": "A one-element array containing the message.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MessageApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.message` system right\n(and is not `system.root`). The response carries\n`code: SystemRightRequired` (package `acl`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "The message id in the URL does not match any stored message.\nThe response carries `code: MessageNotFound` (package\n`message`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageNotFoundError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a message by id.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The message was deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.message` system right\n(and is not `system.root`). The response carries\n`code: SystemRightRequired` (package `acl`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "The message id in the URL does not match any stored message.\nThe response carries `code: MessageNotFound` (package\n`message`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/transitions": {
      "description": "Manage workflow **transitions** — rules that fire when objects are\ninserted, updated or deleted, gated on the object's tags, and run\nactions (set/unset tags, send email, call a webhook, change the\nowner, or invoke a plugin callback). This endpoint is the admin\nsurface: list the defined transitions, replace them. The transitions\nthemselves are evaluated implicitly during the object save pipeline,\nnot through a separate endpoint.\n\nBoth operations require the `system.tagmanager` system right (a\nuser holding `system.root` is always granted it). The endpoint\ntakes no path, query, or header parameters; authentication uses\nthe standard access token (see the API overview).\n\nDiffers from easydb 5: easydb 5 gated only the `POST`, and on the\n`system.rights_management` right; **fylr** gates both methods on\n`system.tagmanager`. easydb 5 returned `400` when the session was\nunauthenticated or lacked the right; **fylr** returns `401`\n(`UserRequired`) and `403` (`SystemRightRequired`) respectively.\n",
      "get": {
        "summary": "List all defined transitions.",
        "description": "Returns the global workflow transitions (those not bound to a\nspecific pool or objecttype), ordered by their `position`.\nPool- and objecttype-scoped transitions are excluded; read those\nthrough the corresponding pool / objecttype endpoints.\n\nRequires the `system.tagmanager` system right.\n\nDiffers from easydb 5: easydb 5's `GET` needed only an\nauthenticated session; **fylr** also requires\n`system.tagmanager`.\n",
        "responses": {
          "200": {
            "description": "Array of transition descriptors.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TransitionApi"
                  },
                  "example": [
                    {
                      "_id": 1,
                      "objecttype_ids": [
                        1
                      ]
                    },
                    {
                      "_id": 2,
                      "objecttype_ids": []
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access\ntoken. Error code `UserRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The user lacks `system.tagmanager` (and is not\n`system.root`). Error code `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Replace the full set of transitions.",
        "description": "Accepts an array of transition descriptors and replaces the\n**global** transition set with them (entries with `_id` are\nupdated; entries without `_id` are created; transitions that\nexist on the server but not in the payload are deleted). A\npartial array therefore removes every omitted global\ntransition. Transitions scoped to a specific pool or objecttype\nare not managed here — they are sent through the corresponding\npool / objecttype endpoints.\n\nRequires the `system.tagmanager` system right. Rejected if the\ninstance is in read-only mode (checked before the right, so a\nread-only instance returns `400 ReadOnlyMode` even to a user\nwithout the right).\n\nThe response echoes the persisted set, with server-issued `_id`s\nfilled in. On success a `X-Fylr-Cache-ID` response header carries\nthe new cache id (format `\u003cstartup-unix\u003e-\u003ccache-id\u003e`), bumped after\nthe transaction commits.\n\nDiffers from easydb 5: **fylr** gates this on `system.tagmanager`\n(easydb 5 used `system.rights_management`); validation failures\nand the read-only rejection surface as `400` with explicit error\n`code`s (`ServerGeneric`, `ReadOnlyMode`) rather than easydb 5's\nbare `400`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TransitionApi"
                },
                "example": [
                  {
                    "confirm": {
                      "de-DE": "Plugin test transition"
                    },
                    "operations": [
                      "UPDATE"
                    ],
                    "sticky": false,
                    "type": "resolve",
                    "objecttype_ids": [
                      21,
                      17,
                      1,
                      27,
                      15
                    ],
                    "actions": [
                      {
                        "type": "fylr_example:set_comment",
                        "info": {
                          "comment": "written by plugin transition"
                        }
                      }
                    ],
                    "who": [
                      {
                        "_basetype": "user",
                        "user": {
                          "_id": 1
                        }
                      }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The persisted transition set, in the same shape as `GET\n/transitions`. Newly-created entries (sent without `_id`)\ncome back with their server-issued `_id`. The order matches\nthe order sent in the request body.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TransitionApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Read-only mode is enabled (code `ReadOnlyMode`, checked\nbefore the right and before parsing), or the payload is\ninvalid. Invalid workflow actions carry their own codes\n(package `transition`): a `webhook` action with no webhook\nselected (`WebhookNotSelected`), with a `name` not declared\nin the base config (`WebhookUnknown`, parameter `name`), or\nwith an unknown `callback` (not `pre_save` /\n`after_commit_async`; `WebhookCallbackUnknown`, parameter\n`callback`); a `change_owner` action without an owner\n(`ChangeOwnerNotSelected`). Everything else is code\n`ServerGeneric`: unparseable JSON; an entry whose `_id`\nmatches no existing transition in the database; an unknown\ntransition `type` (not one of `resolve`, `reject`,\n`exit_resolve`, `exit_reject`, `process`); an unknown\n`operations` value (not `INSERT` / `UPDATE` / `DELETE`); a\n`tagfilter:before` / `tagfilter:after` that lists the same\ntag id more than once; a `who` entry whose `_basetype` is\nneither `user` nor `group`, or that mixes the wrong key for\nits basetype; or an action `type` that matches no built-in\n(`email`, `set_tags`, `webhook`, `change_owner`) and resolves\nto no registered plugin callback.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access\ntoken. Error code `UserRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The user lacks `system.tagmanager` (and is not\n`system.root`). Error code `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/event": {
      "description": "Read, write and subscribe to **events**. fylr writes events for many\nserver-side mutations (object insert/update, collection changes,\nfile deletes, email sends, ...). This endpoint exposes the event log.\n",
      "post": {
        "summary": "Write a single user event.",
        "description": "Allows clients to log user events into the event stream. Any\nauthenticated user may write event types in the **FRONTEND** and\n**PLUGIN** groups (e.g. `SEARCH`, `DETAIL_VIEW`, `FRONTEND_ERROR`).\nWriting event types in any other group (`ADMIN`, `DOWNLOAD`, `EXPORT`,\n`INDEX`, `LOGIN_LOGOUT`, `SYSTEM`, `TASK`, `UPLOAD`) requires\n`system.root` together with `skip_constraints=true` (see the\n`skip_constraints` parameter); a type unknown to the server is always\nrejected with `code: EventTypeNotAllowed`.\nUnlike the other event write operations, `POST /event` is permitted\nwhile the instance is in read-only mode.\n\nDiffers from easydb 5: easydb 5 lets a client insert only `SEARCH` and\n`DETAIL_VIEW`, and only when the matching base config (`system.log.search`\n/ `system.log.detail_view`) is enabled. fylr allows the whole FRONTEND\ngroup (`SEARCH`, `DETAIL_VIEW`, `FRONTEND_ERROR`,\n`ASSET_DOWNLOAD_CONFIRMATION_MESSAGE`) and the PLUGIN group with no\nbase-config gate, plus all other known groups via `system.root` +\n`skip_constraints`.\n",
        "parameters": [
          {
            "name": "background",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If `true`, the event is saved asynchronously: the request returns\n`{\"background\": \"ok\"}` immediately and per-event validation errors\n(e.g. a disallowed `type`) are **not** reported in the response.\n"
          },
          {
            "name": "skip_constraints",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If `true`, all other known event groups (`ADMIN`, `DOWNLOAD`,\n`EXPORT`, `INDEX`, `LOGIN_LOGOUT`, `SYSTEM`, `TASK`, `UPLOAD`)\nmay also be written —\nnot just the FRONTEND/PLUGIN user types — and a top-level `user`\nobject is accepted on the event. Requires `system.root`; a non-root\ncaller that sets it receives a `400 ServerGeneric` error.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "For a synchronous write the stored event is echoed as an\n`EventApi`. With `background=true` the body is `{\"background\":\"ok\"}`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventBackgroundOrApi"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Possible `code` values:\n`EventTypeNotAllowed` (the payload's `type` is unknown, or is not a\nFRONTEND/PLUGIN user type and was not unlocked with root +\n`skip_constraints`),\n`ServerGeneric` (invalid JSON body, an unparseable query filter\nsuch as `id`/`sort`, a non-root caller passing `skip_constraints`,\nor an event carrying a `user`/`user_id` without `skip_constraints`),\nor `ReadOnlyMode` (the instance is in read-only mode; affects the\nwrite/delete operations only, not `POST /event`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/EventTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/event/poll/{fromEventId}": {
      "x-path": "/event",
      "description": "Fetch pollable events with an `_id` greater than `fromEventId`, ordered by\n`_id` ascending and capped at `limit`. The request returns immediately —\nit does **not** block — and the array is empty when no such event exists.\nRequires an authenticated user.\n\nDiffers from easydb 5: in easydb 5 the id segment is optional\n(`/event/poll[/\u003clast_max_id\u003e]`) and defaults to the session's\n`current_max_event_id`. In fylr `fromEventId` is a required path segment;\npoll from the start with `0`.\n",
      "get": {
        "summary": "Fetch pollable events newer than an event id.",
        "description": "Runs a single query for pollable events with `_id` strictly greater\nthan `fromEventId` (ordered by `_id` ascending, up to `limit` rows) and\nreturns immediately; the array may be empty. This is a one-shot poll,\nnot a blocking long-poll — clients repeat the call with the highest\n`_id` they have seen. For a continuous push use `GET /event/stream`.\n",
        "parameters": [
          {
            "name": "fromEventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            },
            "description": "The last event id the caller has seen. Use `0` to poll from\nthe very beginning of the pollable event log.\n"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1,
              "maximum": 1000,
              "default": 25
            },
            "description": "Maximum number of events to return in this response. Default `25`;\nvalues `\u003c= 0` or `\u003e 1000` are clamped to `1000`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Array of new events.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EventApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/event/stream": {
      "x-path": "/event",
      "description": "Subscribe to the event log over a **WebSocket**. The connection is\nupgraded and new pollable events are pushed as they happen, one `EventApi`\nper JSON text frame, until the socket is closed. Inbound client messages\nare discarded. Requires an authenticated user.\n",
      "get": {
        "summary": "WebSocket stream of new events.",
        "description": "Upgrades the connection to a **WebSocket** (the handler calls the\ngorilla/websocket upgrader) and pushes new pollable events as they\nhappen. Each event is sent as one JSON text frame carrying the\n`EventApi` object. The client should connect with the `ws://`/`wss://`\nscheme; any inbound message from the client is discarded.\n",
        "responses": {
          "101": {
            "description": "The connection was upgraded to a WebSocket. New events follow as\nJSON text frames (one `EventApi` per frame) until the socket is\nclosed.\n"
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/event/{eventId}": {
      "x-path": "/event",
      "description": "Read or delete a single event identified by its `_id`. `GET` returns the\nevent as an `EventApi` and requires `system.api.event[get]`; `DELETE`\nremoves it and requires `system.api.event[delete]`. An unknown id yields\n`code: EventNotFound`.\n",
      "get": {
        "summary": "Retrieve a single event by id.",
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            },
            "description": "The event's `_id`."
          }
        ],
        "responses": {
          "200": {
            "description": "The event.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventApi"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for this\noperation: `system.api.event[get]` for reads\n(`GET /event/{eventId}`, `GET /event/list`) or\n`system.api.event[delete]` for deletes\n(`DELETE /event/{eventId}`, `DELETE /event/list`). `system.root`\nalways suffices. There is no per-object ACL on events.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "No stored event has the id given in the URL. The response carries\n`code: EventNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventNotFoundError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a single event by id.",
        "description": "Requires the `system.api.event[delete]` system right (or `system.root`).\nRejected with `400 ReadOnlyMode` while the instance is in read-only mode.\n",
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The event was deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  },
                  "example": {
                    "status": {
                      "acknowledged": "ok"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Possible `code` values:\n`EventTypeNotAllowed` (the payload's `type` is unknown, or is not a\nFRONTEND/PLUGIN user type and was not unlocked with root +\n`skip_constraints`),\n`ServerGeneric` (invalid JSON body, an unparseable query filter\nsuch as `id`/`sort`, a non-root caller passing `skip_constraints`,\nor an event carrying a `user`/`user_id` without `skip_constraints`),\nor `ReadOnlyMode` (the instance is in read-only mode; affects the\nwrite/delete operations only, not `POST /event`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/EventTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for this\noperation: `system.api.event[get]` for reads\n(`GET /event/{eventId}`, `GET /event/list`) or\n`system.api.event[delete]` for deletes\n(`DELETE /event/{eventId}`, `DELETE /event/list`). `system.root`\nalways suffices. There is no per-object ACL on events.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "No stored event has the id given in the URL. The response carries\n`code: EventNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/event/list": {
      "x-path": "/event",
      "description": "Query and bulk-manage events. `GET` lists events filtered by query\nparameters (`type`, `objecttype`, `user_id`, `date_from`/`date_to`, ...),\npaginated and sorted, as `json` or `csv`. `POST` bulk-writes an array of\nevents; `DELETE` bulk-removes every event matching the same query filters.\nReads need `system.api.event[get]`, deletes need `system.api.event[delete]`.\n",
      "get": {
        "summary": "List events (paginated, with filters).",
        "description": "Returns events ordered by `_id` descending by default. The JSON\nresponse is an object `{count, limit, offset, objects[]}`.\n\nFilters and pagination are query parameters. Pagination: `offset`,\n`limit`. Output: `format` (`json` (default) or `csv`); `pretty`\n(JSON only, default `true`). Filters are matched as **IN** lists\n(comma-separated): `id` (id list/ranges, e.g. `1,2-30,4`), `pollable`\n(bool), `type`, `basetype`, `objecttype`, `user_id`, `group_id`,\n`user_type`, `object_id`, `system_object_id`. Time window:\n`date_from`, `date_to` (ISO timestamps, range on `event.timestamp`).\n\n`sort` is a comma-separated list of `field.DIR` (DIR = `ASC`|`DESC`)\nover the fields `_id`, `type`, `schema`, `object_id`,\n`system_object_id`, `object_version`, `timestamp`,\n`user_generated_displayname`.\n\nWith `format=csv` the response is `text/csv` and these output options\napply: `csv_delimiter`, `csv_quote`, `csv_escape`, `csv_explode`,\n`csv_explode_array_concat`, `csv_max_length`, `cvs_use_bom`.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Maximum number of events to return."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Number of events to skip."
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ],
              "default": "json"
            },
            "description": "Response format. `csv` returns `text/csv` instead of JSON."
          },
          {
            "name": "id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Event id filter as a comma-separated list of ids and ranges,\ne.g. `1,2-30,4`.\n"
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of event `type` values to match."
          },
          {
            "name": "objecttype",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of objecttype names to match."
          },
          {
            "name": "user_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of user ids to match."
          },
          {
            "name": "date_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Lower bound (inclusive) on `event.timestamp`."
          },
          {
            "name": "date_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Upper bound on `event.timestamp`."
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated `field.DIR` ordering (DIR = `ASC`|`DESC`).\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Object envelope of matching events (JSON format). With\n`format=csv` the response is `text/csv` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "objects"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "format": "int64",
                      "description": "Total number of events matching the filter (before\n`limit`/`offset`).\n"
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Echo of the effective limit (`0` = unlimited)."
                    },
                    "offset": {
                      "type": "integer",
                      "description": "Echo of the requested offset."
                    },
                    "objects": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EventApi"
                      }
                    }
                  },
                  "example": {
                    "count": 1,
                    "objects": [
                      {
                        "_basetype": "event",
                        "event": {
                          "type": "SEARCH"
                        }
                      }
                    ]
                  }
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string",
                  "description": "CSV rendering of the matching events (one row per event;\n`info.*` columns when `csv_explode=true`).\n"
                }
              }
            }
          },
          "400": {
            "description": "A query filter could not be parsed (e.g. a malformed `id` range,\nan unknown `sort` field/direction, or an unknown `format`). The\nresponse carries `code: ServerGeneric`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerGenericError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for this\noperation: `system.api.event[get]` for reads\n(`GET /event/{eventId}`, `GET /event/list`) or\n`system.api.event[delete]` for deletes\n(`DELETE /event/{eventId}`, `DELETE /event/list`). `system.root`\nalways suffices. There is no per-object ACL on events.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Bulk-write events.",
        "description": "Writes the supplied array of events. Useful for batch tooling. As with\n`POST /event`, any authenticated user may write FRONTEND/PLUGIN event\ntypes; all other known event groups require `system.root` with\n`skip_constraints=true`, and a type unknown to the server is rejected\nwith `code: EventTypeNotAllowed`. Unlike `POST /event`, this\nbulk operation is rejected with `400 ReadOnlyMode` while the instance\nis in read-only mode.\n",
        "parameters": [
          {
            "name": "background",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If `true`, the events are saved asynchronously: the request returns\n`{\"background\": \"ok\"}` immediately and per-event validation errors\n(e.g. a disallowed `type`) are **not** reported in the response.\n"
          },
          {
            "name": "skip_constraints",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "If `true`, all other known event groups (`ADMIN`, `DOWNLOAD`,\n`EXPORT`, `INDEX`, `LOGIN_LOGOUT`, `SYSTEM`, `TASK`, `UPLOAD`)\nmay also be written —\nnot just the FRONTEND/PLUGIN user types — and a top-level `user`\nobject is accepted on each event. Requires `system.root`; a non-root\ncaller that sets it receives a `400 ServerGeneric` error.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EventApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "For a synchronous write the stored events are echoed as an array of\n`EventApi`. With `background=true` the body is `{\"background\":\"ok\"}`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventListBackgroundOrApi"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Possible `code` values:\n`EventTypeNotAllowed` (the payload's `type` is unknown, or is not a\nFRONTEND/PLUGIN user type and was not unlocked with root +\n`skip_constraints`),\n`ServerGeneric` (invalid JSON body, an unparseable query filter\nsuch as `id`/`sort`, a non-root caller passing `skip_constraints`,\nor an event carrying a `user`/`user_id` without `skip_constraints`),\nor `ReadOnlyMode` (the instance is in read-only mode; affects the\nwrite/delete operations only, not `POST /event`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/EventTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Bulk-delete events.",
        "description": "Deletes every event matching the supplied filters. The filters are\nread from the **query string** — the same `EventListQuery` as\n`GET /event/list` (commonly `id=...`, plus `type`, `date_from`,\n`date_to`, `user_id`, ...); there is **no request body**. With no\nfilters the match set is the entire event log, so deletion is\nunbounded. Requires the `system.api.event[delete]` system right\n(or `system.root`), and is rejected with `400 ReadOnlyMode` while the\ninstance is in read-only mode.\n",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Event id filter as a comma-separated list of ids and ranges,\ne.g. `1,2-30,4`. The matched events are deleted.\n"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Maximum number of matched events to delete."
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of event `type` values to match."
          },
          {
            "name": "date_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Lower bound (inclusive) on `event.timestamp`."
          },
          {
            "name": "date_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Upper bound on `event.timestamp`."
          }
        ],
        "responses": {
          "200": {
            "description": "The matched events were deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  },
                  "example": {
                    "status": {
                      "acknowledged": "ok"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. Possible `code` values:\n`EventTypeNotAllowed` (the payload's `type` is unknown, or is not a\nFRONTEND/PLUGIN user type and was not unlocked with root +\n`skip_constraints`),\n`ServerGeneric` (invalid JSON body, an unparseable query filter\nsuch as `id`/`sort`, a non-root caller passing `skip_constraints`,\nor an event carrying a `user`/`user_id` without `skip_constraints`),\nor `ReadOnlyMode` (the instance is in read-only mode; affects the\nwrite/delete operations only, not `POST /event`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/EventTypeNotAllowedError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the system right required for this\noperation: `system.api.event[get]` for reads\n(`GET /event/{eventId}`, `GET /event/list`) or\n`system.api.event[delete]` for deletes\n(`DELETE /event/{eventId}`, `DELETE /event/list`). `system.root`\nalways suffices. There is no per-object ACL on events.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/export": {
      "description": "Manage **exports** — long-running jobs that bundle objects and their\nfiles into a downloadable archive (TAR.GZ or ZIP). All `/export`\nendpoints require an authenticated user (a valid access token, sent as\n`Authorization: Bearer`, `X-Fylr-Authorization: Bearer`, or the\n`access_token` query parameter); there is no dedicated system right for\nthe feature. Exports are user-scoped: each export records the `user_id`\nthat saved it, and the handlers permit access only to that owner or to a\n`system.root` user.\n",
      "get": {
        "summary": "List the authenticated user's exports.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 100
            },
            "description": "Maximum number of entries to return. Defaults to 100.\n"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64",
              "default": 0
            },
            "description": "Pagination offset."
          },
          {
            "name": "filter",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Compact filter expression. Comma-separates ORs, plus-separates\nANDs within an OR, colon separates field from value, pipe\nseparates allowed values. Example:\n`type:download+status:failed|done_with_warnings,type:export|export_incremental`.\nOnly the fields `type` and `status` are filterable; any other\nfield name returns a 400 `Unknown column`. `type` accepts\n`export` / `export_incremental` / `download`; `status` accepts\nthe export states (`new`, `pending`, `processing`, `done`,\n`done_with_warnings`, `failed`).\n\nDiffers from easydb 5: fylr adds the run state\n`done_with_warnings`; easydb 5 documents only `new`, `pending`,\n`processing`, `failed`, and `done`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the user's exports.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportApiList"
                }
              }
            }
          },
          "400": {
            "description": "The `filter` references a field other than `type` or `status`\n(message `Unknown column \"\u003cfield\u003e\"`), or no user is authenticated.\nBoth surface as code `ServerGeneric` (package `ferrors`). This\nroute never returns `403`: it lists only the caller's own exports\n(`user_id = \u003ccaller\u003e`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a new export.",
        "description": "Saves a new export owned by the authenticated user (the stored\n`user_id` is always set to the caller, regardless of any value in the\nbody). There is no owner check on this route.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created export.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportApi"
                }
              }
            }
          },
          "400": {
            "description": "The export could not be saved — e.g. a missing `search`, an\nunknown `type` or `mapping`, a non-`.xsl`/`.xslt` attached file,\nor, on update, a stale `version`. Most of these surface as code\n`ServerGeneric` (package `ferrors`); a version conflict surfaces\nas `VersionMismatch` (package `ferrors`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Another export owned by the same user already uses the\nrequested `name` (code `ExportDuplicateName`, package\n`export`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportDuplicateNameError"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create a new export (alias for POST).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created export.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportApi"
                }
              }
            }
          },
          "400": {
            "description": "The export could not be saved — e.g. a missing `search`, an\nunknown `type` or `mapping`, a non-`.xsl`/`.xslt` attached file,\nor, on update, a stale `version`. Most of these surface as code\n`ServerGeneric` (package `ferrors`); a version conflict surfaces\nas `VersionMismatch` (package `ferrors`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Another export owned by the same user already uses the\nrequested `name` (code `ExportDuplicateName`, package\n`export`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportDuplicateNameError"
                }
              }
            }
          }
        }
      }
    },
    "/export/{exportId}": {
      "x-path": "/export",
      "description": "Read, update, or delete a single export identified by `exportId`.\n`GET` returns the export (rendering detail controlled by the `format`\nquery), `POST` updates its configuration, and `DELETE` removes it. `GET`\nand `DELETE` enforce the owner / `system.root` check; `POST` does not —\nit re-saves the export with `user_id` set to the caller. `DELETE` is\nrefused in read-only mode; `POST` is allowed in read-only mode.\n",
      "get": {
        "summary": "Retrieve an export.",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "short",
                "standard",
                "long"
              ],
              "default": "long"
            },
            "description": "Rendering detail level. Defaults to `long` when omitted. An\nunrecognised value yields a 400 error.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The export.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportApi"
                }
              }
            }
          },
          "400": {
            "description": "The `exportId` in the URL matches no stored export. `LoadById`\nfails with message `export \u003cid\u003e not found`, returned as code\n`ServerGeneric` (package `ferrors`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Update an existing export.",
        "description": "Re-saves the export. The request body must carry the export's `id`\n(matching the URL) and the next `version` (the stored version plus\none); a stale `version` is rejected with a 400 `VersionMismatch`. The\nsaved `user_id` is set to the caller, and there is no separate owner\ncheck on this route. Returns 409 if the new `name` collides with\nanother export owned by the same user.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated export.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportApi"
                }
              }
            }
          },
          "400": {
            "description": "The export could not be saved — e.g. a missing `search`, an\nunknown `type` or `mapping`, a non-`.xsl`/`.xslt` attached file,\nor, on update, a stale `version`. Most of these surface as code\n`ServerGeneric` (package `ferrors`); a version conflict surfaces\nas `VersionMismatch` (package `ferrors`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Another export owned by the same user already uses the\nrequested `name` (code `ExportDuplicateName`, package\n`export`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportDuplicateNameError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete an export.",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The export was deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Either the server is in read-only mode, in which case exports\ncannot be deleted (code `ReadOnlyMode`, package `ferrors`), or\nthe export id in the URL matches no stored export (code\n`ServerGeneric`, package `ferrors`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          }
        }
      }
    },
    "/export/{exportId}/start": {
      "x-path": "/export",
      "description": "Schedule a production run for the export identified by `exportId` and\nreturn the export. Permitted even when the server is in read-only\nmode so existing archives stay downloadable.\n",
      "post": {
        "summary": "Start (or restart) the export's generation.",
        "description": "Schedules a production run for the export. Permitted even when the\nserver is in read-only mode, so downloads keep working.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The export is scheduled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportApi"
                }
              }
            }
          },
          "400": {
            "description": "The `exportId` in the URL matches no stored export. `LoadById`\nfails with message `export \u003cid\u003e not found`, returned as code\n`ServerGeneric` (package `ferrors`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          }
        }
      }
    },
    "/export/{exportId}/stop": {
      "x-path": "/export",
      "description": "Signal the running export identified by `exportId` to stop. The\nrequest waits up to 4 seconds for the export to reach state `failed`,\nthen returns the export.\n",
      "post": {
        "summary": "Stop a running export.",
        "description": "Signals the export to stop and waits up to 4 seconds for it to\nreach state `failed`, then returns the export (via the same\nrendering as `GET /export/{exportId}`). The export must be in state\n`processing`: stopping one in any other state fails with a 400\n(`unable to stop export in status ...`, code `ServerGeneric`). If the\nexport does not reach `failed` within 4 seconds, the request fails\nwith a 400 (`failed to stop export after 4 seconds`, code\n`ServerGeneric`). This route is permitted even in read-only mode.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The export reached state `failed` after the stop signal; the\nexport is returned.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportApi"
                }
              }
            }
          },
          "400": {
            "description": "The `exportId` in the URL matches no stored export. `LoadById`\nfails with message `export \u003cid\u003e not found`, returned as code\n`ServerGeneric` (package `ferrors`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          }
        }
      }
    },
    "/export/{exportId}/tar_gz/": {
      "x-path": "/export",
      "description": "Download the TAR.GZ archive produced for the export identified by\n`exportId`. As a `PathPrefix` mount, a path appended after `tar_gz/`\nserves an individual file extracted from the archive.\n\nDiffers from easydb 5: fylr's TAR route is `tar_gz/` and streams a\ngzip-compressed TAR. easydb 5's anonymous archive download serves a\nplain `.tar`, and its `packer` config offers `zip`, `zip_10mb`,\n`zip_2gb`, and `tar_bz2` (BZip2) — there is no gzip-TAR option.\n",
      "get": {
        "summary": "Download the generated TAR.GZ archive (or a path inside it).",
        "description": "Returns the bytes of the export's TAR.GZ archive. The handler also\naccepts deeper paths (PathPrefix mount) — those serve individual\nfiles extracted from the archive.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The archive (or selected entry) bytes.",
            "content": {
              "application/x-tar": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/gzip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "400": {
            "description": "The `exportId` matches no stored export, so streaming never\nstarts (code `ServerGeneric`, package `ferrors`). Note that once\nthe archive stream has begun (HTTP `200` already sent), per-file\nproduction failures are NOT reported as a JSON error: the ZIP\nhandler embeds the error as an entry inside the archive, and the\nTAR.GZ handler aborts the stream with an inline `500`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/export/{exportId}/zip/": {
      "x-path": "/export",
      "description": "Download the ZIP archive produced for the export identified by\n`exportId`. As a `PathPrefix` mount, a path appended after `zip/`\nserves an individual file extracted from the archive.\n",
      "get": {
        "summary": "Download the generated ZIP archive (or a path inside it).",
        "description": "Returns the bytes of the export's ZIP archive. The handler also\naccepts deeper paths (PathPrefix mount) — those serve individual\nfiles extracted from the archive.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The archive (or selected entry) bytes.",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "400": {
            "description": "The `exportId` matches no stored export, so streaming never\nstarts (code `ServerGeneric`, package `ferrors`). Note that once\nthe archive stream has begun (HTTP `200` already sent), per-file\nproduction failures are NOT reported as a JSON error: the ZIP\nhandler embeds the error as an entry inside the archive, and the\nTAR.GZ handler aborts the stream with an inline `500`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/export/{exportId}/uuid/{uuid}/tar_gz/": {
      "x-path": "/export",
      "description": "Download the TAR.GZ archive produced for a specific run `uuid` of the\nexport identified by `exportId`, rather than the most recent run. As a\n`PathPrefix` mount, a path appended after `tar_gz/` serves an\nindividual file extracted from the archive.\n",
      "get": {
        "summary": "Download the TAR.GZ produced for a specific export run UUID.",
        "description": "Same as `/export/{exportId}/tar_gz/` but addresses a particular\nproduction run identified by `uuid`. Useful for clients that need\nto download a specific historical artifact, not just the most\nrecent one.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The export run UUID."
          }
        ],
        "responses": {
          "200": {
            "description": "The archive (or selected entry) bytes.",
            "content": {
              "application/x-tar": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/gzip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "400": {
            "description": "The `exportId` matches no stored export, so streaming never\nstarts (code `ServerGeneric`, package `ferrors`). Note that once\nthe archive stream has begun (HTTP `200` already sent), per-file\nproduction failures are NOT reported as a JSON error: the ZIP\nhandler embeds the error as an entry inside the archive, and the\nTAR.GZ handler aborts the stream with an inline `500`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/export/{exportId}/uuid/{uuid}/zip/": {
      "x-path": "/export",
      "description": "Download the ZIP archive produced for a specific run `uuid` of the\nexport identified by `exportId`, rather than the most recent run. As a\n`PathPrefix` mount, a path appended after `zip/` serves an individual\nfile extracted from the archive.\n",
      "get": {
        "summary": "Download the ZIP produced for a specific export run UUID.",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The archive (or selected entry) bytes.",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "400": {
            "description": "The `exportId` matches no stored export, so streaming never\nstarts (code `ServerGeneric`, package `ferrors`). Note that once\nthe archive stream has begun (HTTP `200` already sent), per-file\nproduction failures are NOT reported as a JSON error: the ZIP\nhandler embeds the error as an entry inside the archive, and the\nTAR.GZ handler aborts the stream with an inline `500`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/export/{exportId}/file/": {
      "x-path": "/export",
      "description": "Access the individual produced files of the export identified by\n`exportId`. As a `PathPrefix` mount, an appended file path returns\nthat file's bytes, while an empty path or one ending in `/` renders an\nHTML directory index of the export's files. `GET` and `HEAD` are\nsupported.\n",
      "get": {
        "summary": "Download a single file from the export, or list the export's files.",
        "description": "PathPrefix mount. With a file path appended, returns that file's\nbytes. With an empty path or a path ending in `/`, renders an HTML\ndirectory index of the export's produced files (the `exportIndex`\npage). `HEAD` is also accepted and returns the headers only, no\nbody.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The file bytes (when a file path is appended) or the HTML file\nindex (when the path is empty or ends in `/`).\n",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "400": {
            "description": "The requested file could not be produced: e.g. the referenced\nfile is not yet in status `done` (`FileNotDone`), a file version\nor group is unavailable (`FileVersionNotAvailable`,\n`FileGroupNotAvailable`), an api-object path is invalid\n(`ApiObjectPath`), or deep-link access is disabled\n(`DeepLinkAccessByIdDisabled`, `DeepLinkAccessByColumnDisabled`).\nAll carry package `export`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/FileNotDoneError"
                    },
                    {
                      "$ref": "#/components/schemas/FileVersionNotAvailableError"
                    },
                    {
                      "$ref": "#/components/schemas/FileGroupNotAvailableError"
                    },
                    {
                      "$ref": "#/components/schemas/ApiObjectPathError"
                    },
                    {
                      "$ref": "#/components/schemas/DeepLinkAccessByIdDisabledError"
                    },
                    {
                      "$ref": "#/components/schemas/DeepLinkAccessByColumnDisabledError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The requested file does not exist in the export (code\n`FileNotFound`, package `export`). `parameters.file` carries\nthe requested path.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "Headers for a single export file (or the file index).",
        "description": "Same routing as the `GET` form but returns headers only, no body.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Headers for the file or the file index; no body."
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          }
        }
      }
    },
    "/export/{exportId}/uuid/{uuid}/file/": {
      "x-path": "/export",
      "description": "Access the individual produced files of a specific run `uuid` of the\nexport identified by `exportId`. When `uuid` matches one of the\nexport's transport UUIDs, access is granted via that transport\n(deep-link style) instead of the owner check. Behaves like\n`/export/{exportId}/file/` otherwise; `GET` and `HEAD` are supported.\n\nDiffers from easydb 5: fylr grants unauthenticated download access\nthrough `/export/{exportId}/uuid/{uuid}/...`, where `uuid` is a\ntransport UUID. easydb 5 instead exposes\n`/export/\u003cexport-id\u003e/download/\u003csecret-passkey\u003e/\u003cname\u003e.zip` (and\n`.tar`); fylr has no `/download/\u003cpasskey\u003e/` route.\n",
      "get": {
        "summary": "Download a single file (or list files) for a specific export run UUID.",
        "description": "Same as `/export/{exportId}/file/` but addresses a particular\nproduction run identified by `uuid`. When `uuid` matches one of the\nexport's transport UUIDs, access is granted via that transport\n(deep-link style) instead of the owner check. `HEAD` is also\naccepted.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The export run / transport UUID."
          }
        ],
        "responses": {
          "200": {
            "description": "The file bytes (when a file path is appended) or the HTML file\nindex (when the path is empty or ends in `/`).\n",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          },
          "400": {
            "description": "The requested file could not be produced: e.g. the referenced\nfile is not yet in status `done` (`FileNotDone`), a file version\nor group is unavailable (`FileVersionNotAvailable`,\n`FileGroupNotAvailable`), an api-object path is invalid\n(`ApiObjectPath`), or deep-link access is disabled\n(`DeepLinkAccessByIdDisabled`, `DeepLinkAccessByColumnDisabled`).\nAll carry package `export`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/FileNotDoneError"
                    },
                    {
                      "$ref": "#/components/schemas/FileVersionNotAvailableError"
                    },
                    {
                      "$ref": "#/components/schemas/FileGroupNotAvailableError"
                    },
                    {
                      "$ref": "#/components/schemas/ApiObjectPathError"
                    },
                    {
                      "$ref": "#/components/schemas/DeepLinkAccessByIdDisabledError"
                    },
                    {
                      "$ref": "#/components/schemas/DeepLinkAccessByColumnDisabledError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "The requested file does not exist in the export (code\n`FileNotFound`, package `export`). `parameters.file` carries\nthe requested path.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "Headers for a single export file (or the file index) for a run UUID.",
        "description": "Same routing as the `GET` form but returns headers only, no body.\n",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The export run / transport UUID."
          }
        ],
        "responses": {
          "200": {
            "description": "Headers for the file or the file index; no body."
          },
          "403": {
            "description": "The authenticated user is neither the export's owner (matched by\n`user_id`) nor a `system.root` user. The response carries code\n`InsufficientRights` (package `api`); `parameters.resource` is the\nliteral `Export` here (the `DELETE` handler uses `export-{id}`).\nA request with no authenticated user also lands here, except for\ncreate / update / list, which surface a generic `400` instead.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientRightsError"
                }
              }
            }
          }
        }
      }
    },
    "/publish": {
      "description": "Record **publishings** of fylr objects in external systems.\n**fylr has no publishing layer of its own** — the publication\nitself (for example a DataCite DOI, an external gallery page or a\nshare link) is produced and hosted elsewhere. A publish entry is\nfylr's record of such a publication: it ties an object's\n`system_object_id` to the **collector** it was published through\n(a target configured in the base config, e.g. `datacite`) and to\nthe external `publish_uri` where the publication lives, plus a\ndeep-link back into fylr (`easydb_uri`). These endpoints create,\nlist and delete those records — they do not generate or serve the\npublished artifacts.\n",
      "post": {
        "summary": "Record one or more publishings.",
        "description": "The payload is an array of publish descriptors. Requires the\n`system.api.publish[post]` system right and a non-read-only\ninstance.\n\nA descriptor that carries an existing `_id` **updates** that\npublish row in place; a descriptor without `_id` (or with `_id`\n`0`) inserts a new one. Both kinds may be mixed in one request.\n\nDiffers from easydb 5: easydb 5 documents this endpoint as\ninsert-only — \"Only new publishing can be done using this API.\nThere is no possibility to update an existing objects.\" (DELETE +\nre-POST is the documented way to change a publication there). fylr\nadditionally updates the existing row when a descriptor's `_id` is\nset.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PublishApi"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created publish entries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublishApi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The publication could not be created. When a descriptor is\ninvalid the `code` is `PublishUnknownCollector`,\n`PublishInvalidData` or `PublishDeletedObject`\n(`package: object`). A read-only instance rejects the request\nwith `ReadOnlyMode` (this check runs before the rights check);\na request body that is not a valid JSON array of descriptors\nfails with `ServerGeneric`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PublishUnknownCollectorError"
                    },
                    {
                      "$ref": "#/components/schemas/PublishInvalidDataError"
                    },
                    {
                      "$ref": "#/components/schemas/PublishDeletedObjectError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the per-operation system right\n(`system.api.publish[post]`, `system.api.publish[get]`, or\n`system.api.publish[delete]`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "An object referenced by a publish entry's `system_object_id`\ncould not be loaded from the object store — on `POST` the id\nin the payload, on `DELETE` the target object of the publish\nrow being removed (e.g. the object was hard-deleted after the\npublish was recorded). Code `ObjectNotFound`\n(`package: ferrors`, `statuscode: 404`), message\n`Object #\u003csystem_object_id\u003e was not found`. Not raised by an\nunknown id in the request URL — a single `GET` or a `DELETE`\nfor an unknown publish id returns `200`, not `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List publish records.",
        "description": "Requires the `system.api.publish[get]` system right.\n",
        "responses": {
          "200": {
            "description": "Array of publish descriptors.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublishApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the per-operation system right\n(`system.api.publish[post]`, `system.api.publish[get]`, or\n`system.api.publish[delete]`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/publish/{systemObjectId}": {
      "x-path": "/publish",
      "description": "Retrieve a single publish record by its `id`. Despite the path\nparameter name, the value is the publish entry's own `id`, not an\nobject's `system_object_id`. The response is a single-element\narray, or an empty array (still `200`) when no entry has that id.\n",
      "get": {
        "summary": "Retrieve a single publish record by its id.",
        "description": "The path parameter is named `systemObjectId` in the route for\nhistorical reasons; in fact the value is the publish entry's\nown `id`. The handler returns a single-element array (or an\nempty array if no publish has that id). Requires\n`system.api.publish[get]`.\n",
        "parameters": [
          {
            "name": "systemObjectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "Publish entry id (not the system_object_id of an object).\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Array of zero-or-one publish entries that match the id. An\nid matching no stored entry yields an empty array with `200`,\nnot a `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublishApi"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the per-operation system right\n(`system.api.publish[post]`, `system.api.publish[get]`, or\n`system.api.publish[delete]`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/publish/{publishId}": {
      "x-path": "/publish",
      "description": "Delete a single publish record by its `_id`. Requires the\n`system.api.publish[delete]` system right and a non-read-only\ninstance. An unknown id is a no-op that still returns `200` with\n`{\"status\":{\"acknowledged\":\"ok\"}}`.\n",
      "delete": {
        "summary": "Delete a publish record.",
        "description": "Deletes the publish entry with the given `_id`. Requires the\n`system.api.publish[delete]` system right and a non-read-only\ninstance. Deleting an unknown publish id is a no-op that still\nreturns `200` with `{\"status\":{\"acknowledged\":\"ok\"}}`.\n",
        "parameters": [
          {
            "name": "publishId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "The publish entry's `_id`."
          }
        ],
        "responses": {
          "200": {
            "description": "The publication was deleted (or the id did not exist — the\ndelete is a no-op in that case).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The instance is in **read-only** mode, so no publication can\nbe deleted. Code `ReadOnlyMode` (`package: ferrors`), message\n`Read-only mode is enabled.` This check runs before the\nrights check.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the per-operation system right\n(`system.api.publish[post]`, `system.api.publish[get]`, or\n`system.api.publish[delete]`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "An object referenced by a publish entry's `system_object_id`\ncould not be loaded from the object store — on `POST` the id\nin the payload, on `DELETE` the target object of the publish\nrow being removed (e.g. the object was hard-deleted after the\npublish was recorded). Code `ObjectNotFound`\n(`package: ferrors`, `statuscode: 404`), message\n`Object #\u003csystem_object_id\u003e was not found`. Not raised by an\nunknown id in the request URL — a single `GET` or a `DELETE`\nfor an unknown publish id returns `200`, not `404`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/suggest": {
      "description": "Auto-suggest / autocomplete. Given the user's current input,\nreturns candidate completions either as token frequencies\n(`tokens`) or as per-field value matches (`fields`), plus\noptionally the full linked-object descriptors for picker UIs\n(`linked_objects`). Backed by the search index — the same\nlanguage settings apply.\n\nRead-only: the request runs in a read transaction; nothing is\nwritten. The handler enforces no specific right and no login —\nan anonymous request is accepted; results are scoped to whatever\nthe session is allowed to see via the per-user best-mask filter.\n",
      "get": {
        "summary": "Auto-suggest with the request encoded in the URL.",
        "description": "Identical semantics to `POST /suggest`; the JSON request is\npassed verbatim as the `BODY` query parameter. Useful for\nfront ends that prefer not to send a GET body.\n\nThe query parameter name is **`BODY`** (uppercase) — the\nhandler reads `r.URL.Query().Get(\"BODY\")` case-sensitively, so a\nlowercase `body=...` is not picked up; an absent or empty `BODY`\nthen fails JSON parsing and returns a `400`.\n",
        "parameters": [
          {
            "name": "BODY",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "json"
            },
            "description": "JSON-encoded `SuggestRequest`. See the request schema on\n`POST /suggest` for the field set.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Suggestion envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuggestResponse"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request — invalid JSON in `BODY`, an objecttype in\n`objecttypes` or `linked_objecttypes` that does not exist, an\nunresolvable entry in `fields`, or an unknown `tokens_mode`\n(the latter only rejects when token suggestions run, i.e.\nunless `tokens` is `false`). All return `ServerGeneric` /\n`400`; the handler emits no other status.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerGenericError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Auto-suggest with the request as a JSON body.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SuggestRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Suggestion envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuggestResponse"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request — invalid JSON in the request body, an\nobjecttype in `objecttypes` or `linked_objecttypes` that does\nnot exist, an unresolvable entry in `fields`, or an unknown\n`tokens_mode` (the latter only rejects when token suggestions\nrun, i.e. unless `tokens` is `false`). All return\n`ServerGeneric` / `400`; the handler emits no other status.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerGenericError"
                }
              }
            }
          }
        }
      }
    },
    "/l10n/static/{lang}.json": {
      "x-path": "/l10n",
      "description": "Static UI translations — the localisations the front-end and admin\npages need before a user is signed in. Returned as\n`{\u003clang\u003e: {key: text}}` — a single top-level entry keyed by the\nrequested language tag whose value is the flat translation map.\n",
      "get": {
        "summary": "Static UI translations for a language.",
        "parameters": [
          {
            "name": "lang",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Language tag (e.g. `de-DE`, `en-US`). Per key, if the requested\ntag has no value the handler falls back to `en-US`, then to any\nother known language; a key with no value in any language is\nomitted. The result is always keyed by the requested tag.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Single top-level entry keyed by the requested language tag whose\nvalue is the flat translation map. An unknown `lang` still yields\n`{\u003clang\u003e: {...}}` with fallback-filled values.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "description": "`{\u003clang\u003e: {key: translated_text}}` — one entry, keyed by the\nrequested language tag.\n",
                  "example": {
                    "de-DE": {
                      "language.de-DE": "Deutsch (DE-DE)",
                      "language.en-US": "Änglisch (EN-US)",
                      "language.da-DK": "Dänisch (DA-DK)"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/l10n/user/{version}": {
      "x-path": "/l10n",
      "description": "Datamodel translations — labels for objecttypes, masks, fields and\nenums of a specific datamodel version. `version` is `HEAD` (the\nworking copy), `CURRENT` (the most recently committed version,\nresolved server-side), or a positive integer for a specific committed\nversion. Reading requires only an authenticated user.\n",
      "get": {
        "summary": "Datamodel translations for a version.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(HEAD|CURRENT|[1-9][0-9]*)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The datamodel translations as a flat `{key: LocaValue}`\ndocument.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocaApi"
                }
              }
            }
          },
          "400": {
            "description": "The requested datamodel version does not exist, or the supplied\n`version` is not `HEAD`, `CURRENT`, or a positive integer\n(`code: DatamodelVersionNotFound`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatamodelVersionNotFoundError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/l10n/user/HEAD": {
      "x-path": "/l10n",
      "description": "Write the working-copy (`HEAD`) datamodel translations. The handler does\nnot check any user right — it is guarded only by read-only mode. **This is\na full replace**: any generated key omitted from the body is cleared, so\nalways send the complete document (typically the body returned by\n`GET /l10n/user/HEAD`). The write lands on the uncommitted `HEAD` datamodel\n(a fresh working copy is started when `HEAD` was previously committed), so\nthe change reaches `CURRENT` and committed versions only after\n`POST /schema/commit`.\n\nDiffers from easydb 5: easydb 5 requires the system right `system.datamodel`\nwith level `development` to update localizations; fylr checks no user right\nhere (the write is guarded only by read-only mode). easydb 5 also accepts\n`POST /api/v1/l10n/user/{CURRENT|HEAD}` (both `CURRENT` and `HEAD`); fylr\nonly exposes `HEAD` — writing always lands on the working copy.\n",
      "post": {
        "summary": "Update HEAD datamodel translations.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LocaApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The HEAD translations were updated. The response carries\nthe resulting translation document — the same shape as\n`GET /l10n/user/HEAD`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocaApi"
                }
              }
            }
          },
          "400": {
            "description": "The submitted document is malformed (`code: ServerGeneric`), or\nthe instance is in read-only mode (`code: ReadOnlyMode`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/plugin": {
      "description": "Read information about installed plugins, and download the bundled\nplugin assets (JavaScript, CSS, HTML templates, translations).\n",
      "get": {
        "summary": "List installed plugins.",
        "description": "Returns the descriptors of all **enabled** plugins (disabled\nplugins are not exposed here) and — when bundling is enabled\non the instance — the URLs of the concatenated front-end\nasset bundles.\n\nThis endpoint is public: no access token is required.\n",
        "responses": {
          "200": {
            "description": "The plugin inventory and the front-end bundle URLs.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginApiGET"
                }
              }
            }
          }
        }
      }
    },
    "/plugin/bundle.js": {
      "x-path": "/plugin",
      "description": "Serves the concatenated JavaScript of every enabled plugin, in\ndependency load-order. Public (no access token) and cached\nclient-side via the standard fylr cache-id header.\n",
      "get": {
        "summary": "Concatenated plugin JavaScript bundle.",
        "description": "Returns the JavaScript bundle of every enabled plugin, in\nload-order. Cached client-side using the standard fylr\ncache-id header.\n",
        "responses": {
          "200": {
            "description": "The JavaScript bundle.",
            "content": {
              "text/javascript": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/plugin/bundle.css": {
      "x-path": "/plugin",
      "description": "Serves the concatenated CSS of every enabled plugin, in dependency\nload-order. Public (no access token) and cached client-side via the\nstandard fylr cache-id header.\n",
      "get": {
        "summary": "Concatenated plugin CSS bundle.",
        "responses": {
          "200": {
            "description": "The CSS bundle.",
            "content": {
              "text/css": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/plugin/bundle.html": {
      "x-path": "/plugin",
      "description": "Serves the concatenated HTML templates of every enabled plugin, in\ndependency load-order. Public (no access token) and cached\nclient-side via the standard fylr cache-id header.\n",
      "get": {
        "summary": "Concatenated plugin HTML templates.",
        "responses": {
          "200": {
            "description": "The HTML template bundle.",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/plugin/bundle/l10n/{lang}.json": {
      "x-path": "/plugin",
      "description": "Serves the front-end translations of all enabled plugins for the\nrequested `{lang}`, merged into one flat translation map. Public:\nno access token is required.\n",
      "get": {
        "summary": "Concatenated plugin translations for a language.",
        "parameters": [
          {
            "name": "lang",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Language tag (e.g. `de-DE`, `en-US`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Flat translation map merged across all enabled plugins.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/plugin/static/{plugin}/{path}": {
      "x-path": "/plugin",
      "description": "Serves a single bundled static asset of the named `{plugin}` by its\n`{path}` relative to the plugin's static root. The mount is a prefix,\nso `{path}` may span further `/` segments. Public (no access token);\nthe plugin must be enabled.\n",
      "get": {
        "summary": "Download a bundled static asset of a plugin.",
        "description": "Serves a file from the named plugin's static asset directory by\nits path relative to the plugin's static root. The route is a\nprefix mount, so `{path}` may contain further `/` segments.\n\nPublic: no access token is required. The plugin must be enabled.\n",
        "parameters": [
          {
            "name": "plugin",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Plugin name (the manifest `name:`)."
          },
          {
            "name": "path",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Path of the asset relative to the plugin's static root.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The requested asset. The content type depends on the file.\n",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "The plugin exists but is disabled (`code: PluginDisabled`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginDisabledError"
                }
              }
            }
          },
          "404": {
            "description": "No plugin with this name (`code: PluginNotFound`). A missing\nasset within an existing, enabled plugin is reported by the\nfile server itself (a plain-text 404 for disk-backed plugins,\nor a `code: ServerGeneric` 400 when the ZIP read fails for\nzip/url-backed plugins) — not as `PluginNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/plugin/extension/{plugin}/{path}": {
      "x-path": "/plugin",
      "description": "Dispatches to a backend extension endpoint registered by the named\nplugin. The plugin declares extension routes in its manifest; this\nmount forwards a matching request to the plugin's callback, whose\nresponse (status code, headers and body) is entirely plugin-defined.\n\nThe route is registered for **all** HTTP methods (GET, POST, PUT,\nPATCH, DELETE, …); which methods a given extension accepts is up to\nthe plugin. The handler resolves the plugin first: an unknown name\nreturns `code: PluginNotFound` (404) and a disabled plugin returns\n`code: PluginDisabled` (400), both before any auth check. Only then\nis an access token required (`code: UserRequired` / 401 when\nabsent). A request whose `{path}` matches no extension of an\nenabled plugin returns a plain-text 404 (`http.NotFound`), not a\nJSON error body.\n",
      "parameters": [
        {
          "name": "plugin",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Plugin name (the manifest `name:`)."
        },
        {
          "name": "path",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "Extension route path as declared in the plugin manifest. The\nmount is a prefix, so this may contain further `/` segments.\n"
        }
      ],
      "get": {
        "summary": "Call a plugin-defined backend extension endpoint.",
        "description": "Forwards to the plugin's extension callback. The response body and\nstatus are defined by the plugin; extensions may also set custom\n`X-Fylr-Error` / `X-Fylr-Error-Code` headers and return non-2xx\nstatus codes (e.g. 400, 402, 500) with their own body shape.\n\nThe same mount also handles POST, PUT, PATCH and DELETE requests.\n",
        "responses": {
          "200": {
            "description": "Plugin-defined success response. Shape depends entirely on the\nextension implementation.\n"
          },
          "400": {
            "description": "The named plugin exists but is disabled\n(`code: PluginDisabled`). Checked before the access-token\nrequirement.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginDisabledError"
                }
              }
            }
          },
          "401": {
            "description": "The request did not carry a valid access token\n(`code: UserRequired`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "No plugin with this name (`code: PluginNotFound`, standard\nJSON error body). When the plugin exists and is enabled but\nhas no extension matching `{path}`, the handler instead returns\na plain-text `404 page not found` with no JSON body.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/plugin/manage": {
      "x-path": "/plugin/manage",
      "description": "Management API for installed plugins. Every operation requires the\nsystem right `system.root` or `system.plugin`; a request lacking\nboth (including an unauthenticated request) is rejected with\n`code: SystemRightRequired` (403).\n",
      "get": {
        "summary": "List all installed plugins.",
        "description": "Returns every installed plugin — enabled and disabled — with its\nstored row and parsed manifest.\n",
        "responses": {
          "200": {
            "description": "The list of installed plugins.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginManageList"
                }
              }
            }
          },
          "403": {
            "description": "The user holds neither `system.root` nor `system.plugin`\n(`code: SystemRightRequired`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create (install) a plugin.",
        "description": "Installs a new plugin. The body must NOT carry an `id`; `type` is\nrequired and must be one of `disk`, `zip`, `url`. For a ZIP upload,\nset `type: zip` and reference a previously uploaded ZIP asset as\n`zip_file: { \"_id\": \u003cfileId\u003e }`. The plugin's enabled state is\ntaken from the request `enabled` field, so a plugin can be created\nalready enabled.\n\nFails with `code: PluginDuplicateName` (400) if a plugin with the\nsame name already exists, with `code: ReadOnlyMode` when the\ninstance is in read-only mode, and with `code: ServerGeneric`\n(400) when the body carries an `id` or the payload cannot be\nparsed.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PluginManageApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created plugin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginManageApi"
                }
              }
            }
          },
          "400": {
            "description": "A plugin with this name already exists\n(`code: PluginDuplicateName`), the instance is read-only\n(`code: ReadOnlyMode`), or the payload could not be parsed.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PluginDuplicateNameError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "The user holds neither `system.root` nor `system.plugin`\n(`code: SystemRightRequired`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/plugin/manage/{id}": {
      "x-path": "/plugin/manage",
      "description": "Read, update or delete a single installed plugin by its numeric\n`{id}`. Every operation requires the system right `system.root` or\n`system.plugin`; a request holding neither is rejected with\n`code: SystemRightRequired` (403).\n",
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer",
            "format": "int64"
          },
          "description": "Numeric id of the plugin."
        }
      ],
      "get": {
        "summary": "Read one installed plugin.",
        "responses": {
          "200": {
            "description": "The plugin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginManageApi"
                }
              }
            }
          },
          "403": {
            "description": "The user holds neither `system.root` nor `system.plugin`\n(`code: SystemRightRequired`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "No plugin with this id (`code: PluginNotFound`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginNotFoundError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Update an installed plugin.",
        "description": "Updates the plugin identified by `{id}`. The body `id` must match\nthe path `{id}`. Use this to enable/disable a plugin or refresh it\nfrom its source. Fails with `code: ReadOnlyMode` when the instance\nis read-only.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PluginManageApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated plugin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginManageApi"
                }
              }
            }
          },
          "400": {
            "description": "The body `id` does not match the path `{id}`, the instance is\nread-only (`code: ReadOnlyMode`), or the payload could not be\nparsed.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadOnlyModeError"
                }
              }
            }
          },
          "403": {
            "description": "The user holds neither `system.root` nor `system.plugin`\n(`code: SystemRightRequired`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "No plugin with this id (`code: PluginNotFound`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginNotFoundError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete (uninstall) a plugin.",
        "description": "Removes the plugin identified by `{id}`. Fails with\n`code: ReadOnlyMode` when the instance is read-only.\n",
        "responses": {
          "200": {
            "description": "The plugin was deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginDeleteAck"
                }
              }
            }
          },
          "400": {
            "description": "The instance is read-only (`code: ReadOnlyMode`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadOnlyModeError"
                }
              }
            }
          },
          "403": {
            "description": "The user holds neither `system.root` nor `system.plugin`\n(`code: SystemRightRequired`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/xmlmapping/list": {
      "x-path": "/xmlmapping",
      "description": "Manage XML import/export **mappings** — transformations between\nfylr objects and external XML formats (METS/MODS, LIDO, custom\nprofiles, ...). A mapping pairs an XML profile with field-level\nbindings; profiles describe the structure of the external XML.\n",
      "get": {
        "summary": "List all profiles with the mappings built from each.",
        "description": "Returns every registered profile together with the concrete\nmappings derived from it (the `mappings` sub-array). Profiles\nwith no mappings are still included.\n",
        "responses": {
          "200": {
            "description": "Array of profile-with-mappings descriptors.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/XmlMappingProfile"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/xmlmapping/tags": {
      "x-path": "/xmlmapping",
      "description": "Read the metadata tag catalog used by the mapping editor for\ntag-name autocompletion. The catalog is the output of the recipe named\nby `produceConfig.metadata.exif_list` (default `_metadata:_exif_list`),\nrun and streamed straight to the response body. Requires `system.profile`.\n",
      "get": {
        "summary": "List the metadata tags the exif-list recipe knows about.",
        "description": "Runs the recipe named by `produceConfig.metadata.exif_list` (default\n`_metadata:_exif_list`) and copies its output straight to the response\nbody. The default recipe invokes `fylr metadata list -`, which runs\n`exiftool -listx` and converts the XML tag list to JSON — a structured\nlist of every metadata tag exiftool understands, used by the mapping\neditor to autocomplete tag names.\n\nThe response is the recipe's output streamed through unmodified,\nso a custom recipe determines its own shape. With the default\nrecipe the response follows the `XmlMappingTagCatalog` schema:\neach entry in `tags` carries `path`, `group`, `writable`, `type`\nand two capability flags the mapping editor uses to offer only\nthe value-shapes the tag actually supports — `l10n` (the tag is\na localized **lang-alt**) and `list` (the tag is a repeatable\nlist, with `list_type` `Bag` or `Seq`). The two combine into\nfour container kinds: scalar (neither), list (`list`), lang-alt\n(`l10n`), and list-of-lang-alt (both — e.g. `XMP-plus:Custom1`).\nRequires `system.profile`.\n",
        "responses": {
          "200": {
            "description": "The recipe's JSON output, streamed through unmodified\n(`Content-Type: application/json; charset=utf-8`). With the\ndefault `exif_list` recipe this is the exiftool tag catalog.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/XmlMappingTagCatalog"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user has neither the `system.profile` nor the\n`system.root` right. One of them is required for `GET /tags`,\n`GET /mapping/{mapping}`, `PUT /mapping`, `POST /mapping/{mapping}`\nand `DELETE /mapping/{mapping}`. (`GET /list` and\n`GET /profile/{profile}` require only an authenticated user — no\nright.) Response `code` is `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/xmlmapping/profile/{profile}": {
      "x-path": "/xmlmapping",
      "description": "Retrieve a single XML **profile** by name. A profile describes the\nstructure of an external XML format (METS/MODS, LIDO, custom, ...)\nthat mappings are built from. The `{profile}` segment is the stable\nprofile name as returned by `GET /xmlmapping/list`, including the\nsource file extension (e.g. `dc.yml`).\n",
      "get": {
        "summary": "Retrieve a single XML profile.",
        "parameters": [
          {
            "name": "profile",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Stable profile name exactly as returned by `GET /xmlmapping/list`\n— it includes the source file extension, e.g. `dc.yml`. The full\nlist is reachable via `GET /xmlmapping/list`.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The profile descriptor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/XmlMappingProfile"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "400": {
            "description": "The `{mapping}` id (or `{profile}` name) in the URL does not match\nany stored entry. The handler returns a plain error, so the\nresponse `code` is `ServerGeneric` with status `400` — there is no\n`404` for this endpoint.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/xmlmapping/mapping": {
      "x-path": "/xmlmapping",
      "description": "Create a new XML **mapping** — the field-level bindings that pair an\nXML profile with fylr objects for import/export. The mapping is sent\nas an `XmlMappingApi` body. Requires `system.profile`. Use\n`POST /xmlmapping/mapping/{mapping}` to update an existing mapping.\n",
      "put": {
        "summary": "Create a new mapping.",
        "description": "The body's `id` is ignored on create — a fresh id is drawn from the\n`mapping.id` sequence and the row is inserted into the `mapping` table\n(plus `mapping_field` / `mapping_field_easydb`). The same handler serves\n`POST /xmlmapping/mapping/{mapping}` for updates.\n\nDiffers from easydb 5: easydb 5 stores each mapping as a JSON file in the\nschema folder (`schema/\u003cdb\u003e/\u003ccurrent\u003e/xmlmapping-mappings/\u003cmapping_id\u003e.json`).\nfylr stores mappings directly in the `mapping` / `mapping_field` /\n`mapping_field_easydb` database tables — there is no per-mapping file and\nno schema-folder path.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/XmlMappingApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created mapping.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/XmlMappingApi"
                }
              }
            }
          },
          "400": {
            "description": "The body failed validation — for example an unknown `easydb` field\ntype, a `text_fixed`/`deep_link_url` source placed among the\ntext/custom sources, a field name that is not a valid target column,\nan `idTable` (objecttype id) that does not exist, or a recipe config\nthat names a recipe the mapping does not use. A duplicate field\n`name` within the mapping hits the `mapping_field` unique index and\nsurfaces as `DatabaseUniqueKeyViolation`. (An unknown `profile`\nname is accepted silently — it is not validated on save.) Returned\nwith `code` `ReadOnlyMode` when the instance is in read-only mode —\nthis read-only check runs first, before the right check and before\nthe body is decoded.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user has neither the `system.profile` nor the\n`system.root` right. One of them is required for `GET /tags`,\n`GET /mapping/{mapping}`, `PUT /mapping`, `POST /mapping/{mapping}`\nand `DELETE /mapping/{mapping}`. (`GET /list` and\n`GET /profile/{profile}` require only an authenticated user — no\nright.) Response `code` is `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/xmlmapping/mapping/{mapping}": {
      "x-path": "/xmlmapping",
      "description": "Retrieve (`GET`), update (`POST`) or delete (`DELETE`) a single XML\n**mapping**, addressed by its numeric `{mapping}` id. Mappings carry\nthe field-level bindings between fylr objects and an XML profile.\n`POST` and `DELETE` require `system.profile`; deleting a mapping that\nis still linked from collections' upload settings needs the\n`delete_policy=delete` confirmation.\n",
      "get": {
        "summary": "Retrieve an XML mapping.",
        "parameters": [
          {
            "name": "mapping",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The mapping's numeric id (parsed with `pflib.GetInt`); a non-numeric\nor `0` value resolves to id `0`, which matches no mapping.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The mapping descriptor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/XmlMappingApi"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user has neither the `system.profile` nor the\n`system.root` right. One of them is required for `GET /tags`,\n`GET /mapping/{mapping}`, `PUT /mapping`, `POST /mapping/{mapping}`\nand `DELETE /mapping/{mapping}`. (`GET /list` and\n`GET /profile/{profile}` require only an authenticated user — no\nright.) Response `code` is `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "400": {
            "description": "The `{mapping}` id (or `{profile}` name) in the URL does not match\nany stored entry. The handler returns a plain error, so the\nresponse `code` is `ServerGeneric` with status `400` — there is no\n`404` for this endpoint.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Update an existing XML mapping.",
        "parameters": [
          {
            "name": "mapping",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The mapping's numeric id, written into the body's `id` before saving.\nMust be `\u003e 0`, otherwise the request fails with `ServerGeneric` `400`.\nAn id that matches no row makes the `UPDATE` a no-op (no `404`).\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/XmlMappingApi"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated mapping.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/XmlMappingApi"
                }
              }
            }
          },
          "400": {
            "description": "The body failed validation — for example an unknown `easydb` field\ntype, a `text_fixed`/`deep_link_url` source placed among the\ntext/custom sources, a field name that is not a valid target column,\nor a recipe config that names a recipe the mapping does not use. A\nduplicate field `name` within the mapping hits the\n`mapping_field` unique index and surfaces as\n`DatabaseUniqueKeyViolation`. Returned with `code` `ReadOnlyMode`\nwhen the instance is in read-only mode — this read-only check runs\nfirst, before the right check and before the body is decoded.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user has neither the `system.profile` nor the\n`system.root` right. One of them is required for `GET /tags`,\n`GET /mapping/{mapping}`, `PUT /mapping`, `POST /mapping/{mapping}`\nand `DELETE /mapping/{mapping}`. (`GET /list` and\n`GET /profile/{profile}` require only an authenticated user — no\nright.) Response `code` is `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete an XML mapping.",
        "parameters": [
          {
            "name": "mapping",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The mapping's numeric id."
          },
          {
            "name": "delete_policy",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "delete"
              ]
            },
            "description": "Resolves the `202` confirmation that is returned when the mapping\nis still linked from one or more collections' upload settings.\nThe only accepted value is `delete`, which **unlinks** the mapping\nfrom every affected collection (sets\n`collection_create_object.mapping_id` to `NULL`) and then deletes\nthe mapping — it is a save-side-effect switch, not a no-op\nconfirmation. Omit it on the first call to receive the `202`\nlisting the affected collections.\n"
          }
        ],
        "responses": {
          "200": {
            "description": "The mapping was deleted (no collections linked it, or the unlink\nwas confirmed with `delete_policy=delete`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "acknowledged"
                  ],
                  "properties": {
                    "acknowledged": {
                      "type": "boolean",
                      "description": "Always `true` when the mapping was deleted."
                    }
                  },
                  "example": {
                    "acknowledged": true
                  }
                }
              }
            }
          },
          "202": {
            "description": "The mapping is still linked from one or more collections' upload\nsettings. Re-send the same request with `?delete_policy=delete` to\nunlink it from those collections and delete it.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/XmlMappingDelete202"
                }
              }
            }
          },
          "400": {
            "description": "Returned with `code` `ReadOnlyMode` when the instance is in\nread-only mode — this is checked before the right check and before\nthe mapping is loaded. With `code` `UnknownDeletePolicy` when\n`delete_policy` is present but not `delete`. With `code`\n`ServerGeneric` when the `{mapping}` id matches no stored mapping\n(the loader returns a plain error — there is no `404`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user has neither the `system.profile` nor the\n`system.root` right. One of them is required for `GET /tags`,\n`GET /mapping/{mapping}`, `PUT /mapping`, `POST /mapping/{mapping}`\nand `DELETE /mapping/{mapping}`. (`GET /list` and\n`GET /profile/{profile}` require only an authenticated user — no\nright.) Response `code` is `SystemRightRequired`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/oai": {
      "description": "[OAI-PMH](https://www.openarchives.org/OAI/openarchivesprotocol.html)\nendpoint. Implements the Open Archives Initiative Protocol for\nMetadata Harvesting (version 2.0) so external harvesters can pull\nmetadata from fylr. The protocol uses a single URL with a `verb`\nquery parameter and returns XML.\n\nMust be enabled in the base config (`fylr.oai_pmh.enabled = true`),\notherwise every request returns HTTP 400 with `code: OAIpmhNotEnabled`.\nProtocol-level errors are returned inside the XML response body as an\n`\u003cerror code=\"…\"\u003e` element AND carry the matching HTTP status:\n`badArgument` / `badVerb` / `cannotDisseminateFormat` /\n`badResumptionToken` → 400, `idDoesNotExist` → 404, internal failures\n→ 500. Only a successful harvest is `200 OK`.\n\nThe endpoint requires no rights and accepts anonymous requests: when no\nuser can be derived from the session, the built-in `system:oai_pmh`\nuser is used. There is no read-only-mode guard. A `ListRecords` or\n`GetRecord` harvest logs an `OBJECT_DOWNLOAD` event per record (written\nin a background transaction), but the request itself runs in a read\ntransaction — nothing else is persisted.\n",
      "get": {
        "summary": "OAI-PMH protocol entry point.",
        "description": "The behaviour depends on the `verb` query parameter. See the\nOAI-PMH specification for the full request/response shape.\n",
        "parameters": [
          {
            "name": "verb",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "Identify",
                "ListMetadataFormats",
                "ListSets",
                "ListIdentifiers",
                "ListRecords",
                "GetRecord"
              ]
            },
            "description": "OAI-PMH verb."
          },
          {
            "name": "identifier",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "OAI-PMH record identifier, e.g.\n`oai:\u003cnamespace_identifier\u003e:\u003cuuid\u003e`. The prefix is `oai:` plus\nthe configured `fylr.oai_pmh.namespace_identifier` (just `oai:`\nwhen unset). Required for `GetRecord`; ignored by the other\nverbs.\n"
          },
          {
            "name": "metadataPrefix",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Metadata format prefix. Required by fylr for `GetRecord` and\n`ListRecords`; per the OAI-PMH spec it is also expected for\n`ListIdentifiers`, though fylr does not currently reject a\n`ListIdentifiers` request that omits it. Built-in values:\n`oai_dc` and `easydb`. Each XSLT sheet enabled for OAI-PMH in\nthe base config adds a `xslt-\u003cname\u003e` prefix. Call\n`verb=ListMetadataFormats` to enumerate the prefixes available\non a given instance. An unknown prefix yields\n`\u003cerror code=\"cannotDisseminateFormat\"\u003e` (HTTP 400).\n"
          },
          {
            "name": "set",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Set spec (optional for `ListIdentifiers`, `ListRecords`).\n"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "UTC datestamp lower bound (UTC date or full datetime\naccepted, per the OAI-PMH spec).\n"
          },
          {
            "name": "until",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "UTC datestamp upper bound."
          },
          {
            "name": "resumptionToken",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Resumption token issued by a previous `ListIdentifiers`,\n`ListRecords` or `ListSets` response. Must not be combined with\n`from`, `until`, `limit`, `set` or `metadataPrefix`, and must\nmatch the verb of the request that issued it; an expired token\nyields `\u003cerror code=\"badArgument\"\u003e`.\n"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "fylr extension (not part of OAI-PMH). Maximum records per page\nfor `ListRecords` / `ListIdentifiers`. Defaults to the base\nconfig `fylr.oai_pmh.records_limit` (else 100); values are\nclamped to a maximum of 10000. Must not be combined with\n`resumptionToken`.\n"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "fylr extension (not part of OAI-PMH). Starting offset into the\nresult list. Normally supplied via `resumptionToken` instead.\n"
          },
          {
            "name": "event.info",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "fylr extension (not part of OAI-PMH). JSON object string\nattached to the `OBJECT_DOWNLOAD` event logged for each record\nharvested by a `ListRecords` or `GetRecord` request\n(e.g. `{\"custom_info\":\"...\"}`).\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful OAI-PMH response document. Protocol-level errors are\nencoded inside the XML body as `\u003cerror code=\"…\"\u003e` and also set\nthe matching HTTP status (400 / 404 / 500), so this 200 applies\nto successful harvests only.\n",
            "content": {
              "text/xml": {
                "schema": {
                  "type": "string",
                  "description": "An OAI-PMH XML response."
                }
              }
            }
          },
          "400": {
            "description": "Either OAI-PMH is disabled in the base config\n(`fylr.oai_pmh.enabled = false`) — a JSON error envelope with\n`code: OAIpmhNotEnabled` — or a protocol-level request error\n(`badArgument`, `badVerb`, `cannotDisseminateFormat`,\n`badResumptionToken`) returned as an OAI-PMH XML document with an\n`\u003cerror code=\"…\"\u003e` element.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAIpmhNotEnabledError"
                }
              },
              "text/xml": {
                "schema": {
                  "type": "string",
                  "description": "OAI-PMH XML response carrying an `\u003cerror code=\"…\"\u003e`\nelement for the protocol-level error.\n"
                }
              }
            }
          },
          "404": {
            "description": "Protocol-level error `idDoesNotExist` (the `GetRecord`\n`identifier` matched no readable object) returned as an OAI-PMH\nXML document with an `\u003cerror code=\"idDoesNotExist\"\u003e` element.\n",
            "content": {
              "text/xml": {
                "schema": {
                  "type": "string",
                  "description": "OAI-PMH XML response carrying an `\u003cerror code=\"…\"\u003e`\nelement for the protocol-level error.\n"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure while building the response, returned as an\nOAI-PMH XML document with `\u003cerror code=\"internalServerError\"\u003e`.\n",
            "content": {
              "text/xml": {
                "schema": {
                  "type": "string",
                  "description": "OAI-PMH XML response carrying\n`\u003cerror code=\"internalServerError\"\u003e`.\n"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "HEAD on the OAI-PMH endpoint.",
        "description": "Runs the same logic as `GET /oai` (same handler) but the harvester\nreceives only the response headers and HTTP status — no body. A\nmalformed request still yields the matching status, e.g. an unknown\n`verb` returns 400.\n",
        "parameters": [
          {
            "name": "verb",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OAI-PMH service is available and the request succeeded; no body\nis returned.\n"
          },
          "400": {
            "description": "OAI-PMH is disabled, or the request is malformed\n(e.g. an unknown `verb`); no body is returned.\n"
          },
          "404": {
            "description": "Protocol-level not-found error (`idDoesNotExist`); no body is\nreturned.\n"
          },
          "500": {
            "description": "Internal failure while building the response; no body is\nreturned.\n"
          }
        }
      }
    },
    "/WebDAV/{collectionUuid}/{path}": {
      "x-path": "/WebDAV",
      "description": "The **read/write** [WebDAV](http://www.webdav.org/specs/rfc4918.html)\n(RFC 4918) interface to **fylr**'s collections, mounted at\n`/api/v1/WebDAV`. Each WebDAV directory maps to a **fylr** collection;\neach WebDAV file maps to a file linked from that collection — so you can\nbrowse, download, upload, rename and delete a collection's files live.\nFor the separate **drop-only** ingest share, see `/api/v1/hotfolder`\nbelow; the two are independent mounts with independent enable flags.\n\nMust be enabled in the base config (`webdav.read_write_access =\ntrue`), otherwise every request returns 503 with `code:\nWebdavNotEnabled`. The same flag gates both reading and writing.\n\nThis endpoint performs **no client authentication** — the route is\nregistered with no token check. Knowledge of the collection's UUID,\nwhich forms the path, is the only access capability: anyone who can\nreach the URL with a valid collection UUID can mount it. Clients must\nconnect **as guest** and send no credentials — for example, in macOS\nFinder's *Connect to Server* dialog, choose *Connect As: Guest*. There\nis no Bearer-token, `X-Fylr-Authorization`, `access_token` or HTTP\nBasic authentication here; the only gate is whether WebDAV is enabled\n(above). Server-side, the operation acts as the owner of the target\ncollection.\n\n**WebDAV methods.** `GET`, `HEAD`, `OPTIONS`, `POST`, `PUT` and `DELETE`\nare documented as operations below. The collection-specific WebDAV verbs\n— which the OpenAPI renderer cannot list as operations — behave as\nfollows:\n\n  * `PROPFIND` — the WebDAV directory listing: list a collection's\n    contents. The `Depth` header must be `0` or `1` (`400` otherwise);\n    the response is a `207` multistatus XML body.\n  * `PROPPATCH` — accepted for client compatibility only; no properties\n    are stored. It behaves like `PROPFIND` and echoes the current\n    property values.\n  * `MKCOL` — create a collection (`201`; idempotent — also `201` if the\n    collection already exists). `409` when a parent in the path is\n    missing or the path already exists as a file.\n  * `MOVE` — rename a collection within its parent (`201`). `409` for a\n    missing source, an existing destination, a non-collection target, or\n    a cross-parent move; files cannot be moved.\n  * `LOCK` / `UNLOCK` — WebDAV write locks. `LOCK` returns `200` (refresh)\n    or `201` (new) with a `Lock-Token` header and an XML lock-discovery\n    body; `UNLOCK` returns `204`. A token mismatch returns `423`.\n\n`COPY` is not supported and returns `405`. As with the operations below,\nevery verb returns `503` with `code: WebdavNotEnabled` when WebDAV is\ndisabled, and writes return `400` `ReadOnlyMode` in read-only mode.\n",
      "parameters": [
        {
          "name": "collectionUuid",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "The first path segment is the collection UUID. The WebDAV URL of\na collection (its `_hotfolder_upload_urls` entry of type\n`webdav`) ends in this UUID. A request to a bare collection UUID\nlists that collection.\n"
        },
        {
          "name": "path",
          "in": "path",
          "required": false,
          "schema": {
            "type": "string"
          },
          "description": "Any further path segments after the collection UUID are the\ndisplay names of sub-collections, ending in a file display name.\nMay be empty to address the collection itself.\n"
        }
      ],
      "get": {
        "summary": "Download a file (or list a collection — depending on path).",
        "responses": {
          "200": {
            "description": "For a file path: the file contents. For a directory path:\nan HTML index page listing the entries.\n",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "The path does not exist."
          },
          "503": {
            "description": "WebDAV is disabled in the base config. The response carries\n`code: WebdavNotEnabled`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebdavNotEnabledError"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "Probe a file's existence and metadata.",
        "responses": {
          "200": {
            "description": "The file exists."
          },
          "404": {
            "description": "The path does not exist."
          },
          "503": {
            "description": "WebDAV is disabled in the base config (`code:\nWebdavNotEnabled`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebdavNotEnabledError"
                }
              }
            }
          }
        }
      },
      "options": {
        "summary": "Advertise the supported WebDAV methods for this resource.",
        "responses": {
          "200": {
            "description": "The `DAV:`, `Allow:` and related headers describe what is\nsupported. Body is empty. Note that the advertised `Allow`\nset lists COPY and PROPPATCH for client compatibility, even\nthough COPY returns 405 and PROPPATCH behaves like PROPFIND.\n"
          },
          "503": {
            "description": "WebDAV is disabled in the base config (`code:\nWebdavNotEnabled`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebdavNotEnabledError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "WebDAV POST — handled by the same code path as GET/HEAD. fylr\naccepts it for client compatibility.\n",
        "responses": {
          "200": {
            "description": "The POST was processed."
          },
          "404": {
            "description": "The path does not exist."
          },
          "503": {
            "description": "WebDAV is disabled in the base config (`code:\nWebdavNotEnabled`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebdavNotEnabledError"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Upload a file and link it to the collection.",
        "responses": {
          "201": {
            "description": "The file was uploaded and linked to a new or existing object.\nThe response carries an `X-Fylr-System-Object-Id` header for\neach affected object.\n"
          },
          "400": {
            "description": "The upload was rejected — a dot-prefixed filename (`code:\nDotFilenameNotAllowed`), the collection has no upload\nconfigured or no matching object (`code:\nCollectionUploadNoObjectFound`), or the instance is in\nread-only mode (`code: ReadOnlyMode`).\n"
          },
          "409": {
            "description": "A parent collection in the path does not exist, or the target\ncannot be resolved.\n"
          },
          "423": {
            "description": "The resource is locked and the request did not carry the\nmatching lock token (`code: ResourceLocked`).\n"
          },
          "503": {
            "description": "WebDAV is disabled in the base config (`code:\nWebdavNotEnabled`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebdavNotEnabledError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a file.",
        "responses": {
          "200": {
            "description": "The resource was deleted."
          },
          "400": {
            "description": "The instance is in read-only mode (`code: ReadOnlyMode`).\n"
          },
          "404": {
            "description": "The path does not exist."
          },
          "423": {
            "description": "The resource is locked and the request did not carry the\nmatching lock token (`code: ResourceLocked`).\n"
          },
          "503": {
            "description": "WebDAV is disabled in the base config (`code:\nWebdavNotEnabled`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebdavNotEnabledError"
                }
              }
            }
          }
        }
      }
    },
    "/hotfolder/{collectionUuid}/{path}": {
      "x-path": "/hotfolder",
      "description": "A **drop-only** ingest share at `/api/v1/hotfolder`, distinct from the\nread/write `/api/v1/WebDAV` mount above. Where `/WebDAV` maps WebDAV\noperations onto collections live, the hotfolder is a real on-disk\nstaging directory (the API service's `WebDAVHotfolderPath`) served by\nthe Go standard-library `webdav.Handler`. You **drop files in**; a\nbackground crawler imports each one into the matching collection and\ndeletes it. You do **not** read a collection's records back through it.\n\n**Layout.** The on-disk directory holds one sub-directory per\ncollection, named by the collection UUID, created automatically for\nevery collection that accepts objects (`objects_allowed`). A file is\ntherefore dropped at\n`/api/v1/hotfolder/{collectionUuid}/\u003c...\u003e/\u003cfilename\u003e`. A file placed at\nthe top level (no collection UUID) is ignored.\n\n**Ingestion.** A single crawler walks the directory and imports a file\nonly once it has settled — its size and modification time must be\nunchanged for a configurable delay (15 s by default) — so half-written\nuploads are not grabbed. Empty files, dot-files and `hotfolder.log` are\nskipped; when both a JPEG and a non-JPEG of the same name are pending,\nthe non-JPEG is imported first. On import the file is renamed to\n`IMPORTING-\u003cname\u003e`, uploaded into the collection identified by the UUID\n(creating a record / linked file, exactly as a `PUT` on the `/WebDAV`\nmount would), then deleted. The path below the collection UUID is kept\nas the stored file path; files in sub-directories are imported flat. A\nfailed import is renamed to `ERROR-\u003cname\u003e` with a `\u003cname\u003e.log` beside\nit. Every attempt is appended as a TSV row to `hotfolder.log` inside the\ncollection's directory, with columns `date`, `user`, `path`, `file`,\n`size`, `system_object_id`, `file_eas_id`, `status`, `msg`.\n\n**Enablement.** Served only when `webdav.hotfolder = true`, a hotfolder\npath is configured, and the instance runs a **single backend**;\notherwise every request returns 503 with `code: WebdavNotEnabled`. This\ngate is independent of `webdav.read_write_access`.\n\n**Authentication.** As with `/WebDAV`, the share performs **no client\nauthentication** — connect as guest and send no credentials. The import\nruns server-side as the owner of the target collection.\n\nBeing a stdlib `webdav.Handler` it accepts the full WebDAV method set,\nbut only `PUT` (drop a file) and `MKCOL` (create a sub-directory) do\nanything meaningful; `GET` / `PROPFIND` expose the on-disk staging area\n(files still pending, plus any `IMPORTING-` / `ERROR-` markers and\n`hotfolder.log`), never the collection's actual contents.\n",
      "parameters": [
        {
          "name": "collectionUuid",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "The collection to ingest into — the name of its auto-created\nhotfolder sub-directory, which is the collection UUID. A file must\nbe dropped under a collection UUID to be imported; files at the\nhotfolder root are ignored.\n"
        },
        {
          "name": "path",
          "in": "path",
          "required": false,
          "schema": {
            "type": "string"
          },
          "description": "Any further path below the collection UUID. Sub-directories are\nallowed (the crawler imports their files flat); the final segment is\nthe dropped file's name.\n"
        }
      ],
      "put": {
        "summary": "Drop a file into the collection's hotfolder for ingestion.",
        "description": "The file is written to the on-disk staging directory. It is imported\ninto the collection — creating a record / linked file — by the crawler\nonce it has settled, **not** synchronously with this request. Watch\n`hotfolder.log` in the collection directory, or the new objects in the\ncollection, for the outcome.\n",
        "responses": {
          "201": {
            "description": "The file was written to the staging directory."
          },
          "204": {
            "description": "An existing staged file was overwritten."
          },
          "503": {
            "description": "The hotfolder share is not enabled (`code: WebdavNotEnabled`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebdavNotEnabledError"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Read the on-disk staging area (not the collection's objects).\n",
        "responses": {
          "200": {
            "description": "The bytes of a staged file, an `IMPORTING-`/`ERROR-` marker, or\n`hotfolder.log`.\n",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "description": "The path does not exist on disk."
          },
          "503": {
            "description": "The hotfolder share is not enabled (`code: WebdavNotEnabled`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebdavNotEnabledError"
                }
              }
            }
          }
        }
      }
    },
    "/objects/{path+}": {
      "x-path": "/objects",
      "description": "**Deep link** access to a stored object or one of its files via a\n**structured path grammar** (not an opaque token). The path after\n`/objects/` is an ordered sequence of selectors that **fylr** parses\nsegment by segment and resolves directly against the object store.\n\nMust be enabled in the base config\n(`system.deep_link_access.enabled`); when it is off every request\nreturns 400 with `code: DeepLinkAccessDisabled`.\n\nNo system right is required to call the endpoint and no token is\nmandatory: if the request carries a valid session that user is used,\notherwise the request runs as the built-in `deep_link` system user.\n\n**Differs from easydb 5:** there is no `auth` query parameter. easydb 5\ndocuments an `auth` parameter to select the system user (`deep_link`,\ndefault, or `oai_pmh`); **fylr** always uses the session user and falls\nback only to the `deep_link` system user — `oai_pmh` cannot be selected\nhere.\n\nObject-level rights are still enforced once the object is resolved —\na caller lacking the object read right, or (when no `mask/\u003cname\u003e` is\ngiven) having no accessible mask, gets 403\n`ObjectInsufficientRights`, and a missing asset-download right on a\n`file/...` selector gets 403 `ObjectInsufficientAssetDownloadRight`.\n\nExactly **one** object selector is required:\n\n  * `id/\u003csystem-object-id\u003e` — requires\n    `system.deep_link_access.allow_access_by_id`.\n  * `uuid/\u003cuuid\u003e`.\n  * `column/\u003cobjecttype\u003e/\u003ccolumn\u003e/\u003cvalue\u003e` — requires\n    `system.deep_link_access.allow_access_by_column`. A value that\n    matches more than one object is rejected.\n\n**Differs from easydb 5:** the config keys are\n`system.deep_link_access.allow_access_by_id` and\n`...allow_access_by_column`. easydb 5 documents these as\n`allow_access_by_ids` (plural) and `allow_access_by_unique_columns`.\n\nOptional selectors (each at most once):\n\n  * `mask/\u003cmask-name\u003e` — render through a named mask.\n  * a version qualifier after an `id`/`uuid` object selector:\n    `/latest` or `/version/\u003cn\u003e`.\n  * a file selector: `file/standard/\u003cn\u003e`, `file/all/\u003cn\u003e`,\n    `file/id/\u003cn\u003e`, or `file/column/\u003ccolumn\u003e[/\u003cnth\u003e]`.\n  * `file_browser/preferred` or `file_browser/\u003cn\u003e`.\n  * `file_version/name/\u003cname\u003e` or `file_version/group/\u003cgroup\u003e`.\n  * `format/\u003cfmt\u003e` (see below).\n  * `disposition/inline` or `disposition/attachment`.\n\nSupported `format` values: `json` (the default when no `format` and\nno `file/...` selector are given), `xml_easydb`, `csv`, `html`,\n`xslt/\u003csheet-name\u003e` (the sheet must be enabled for `/api/objects`),\nand `iiif` (only as `format/iiif/v3/manifest.json`, with no `file/...`\nselector). When a `file/...` selector is present and no `format` is\ngiven, the raw file bytes are served.\n\n**Differs from easydb 5:** **fylr** also serves `html` and `iiif`\n(`iiif/v3/manifest.json`). easydb 5 documents only `json`,\n`xml_easydb`, `xslt`, and `csv`.\n\nThe response `Content-Type` is set by the chosen format or the\nunderlying EAS file's MIME type.\n\nExamples:\n\n  * `GET /api/v1/objects/id/42`\n  * `GET /api/v1/objects/uuid/nes1/format/html`\n  * `GET /api/v1/objects/column/keywords/keyword/Gold`\n  * `GET /api/v1/objects/id/42/latest/file/all/1`\n  * `GET /api/v1/objects/id/42/version/1/format/xslt/style1`\n  * `GET /api/v1/objects/id/42/mask/images__all_fields/format/iiif/v3/manifest.json`\n",
      "parameters": [
        {
          "name": "path",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "description": "The structured deep-link selector path, e.g. `id/42`,\n`uuid/nes1/format/html`, `column/keywords/keyword/Gold`, or\n`id/42/latest/file/standard/1`. This is **not** an opaque token;\neach segment is a selector resolved directly against the object\nstore.\n"
        },
        {
          "name": "disposition",
          "in": "query",
          "required": false,
          "schema": {
            "type": "string",
            "enum": [
              "inline",
              "attachment"
            ]
          },
          "description": "Force the `Content-Disposition`. `attachment` forces a download;\nany other value (or absent) yields the default inline\ndisposition. OR-ed with an in-path `disposition/attachment`\nselector — only the value `attachment` changes behavior as a\nquery parameter.\n"
        }
      ],
      "get": {
        "summary": "Resolve a deep link and serve the underlying resource.",
        "responses": {
          "200": {
            "description": "The deep link resolved successfully. The response body is the\nobject export (`json`/`xml_easydb`/`csv`/`html`/`xslt`/`iiif`)\nor, with a `file/...` selector, the file's raw bytes. The\nresponse carries `Cache-Control: no-cache, must-revalidate` and\na `Content-Type` matching the chosen format or the underlying\nEAS file's MIME type. Pass `?disposition=attachment` (or an\nin-path `disposition/attachment` selector) to force a download.\n",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "The request cannot be served. `code: DeepLinkAccessDisabled`\nwhen deep-link access is off in the base config;\n`DeepLinkAccessByIdDisabled` / `DeepLinkAccessByColumnDisabled`\nwhen the corresponding `allow_access_by_id` /\n`allow_access_by_column` flag is off; `ApiObjectPath` when the\nselector path is malformed or the addressed object / version /\ncolumn cannot be resolved; `FileVersionNotAvailable` /\n`FileGroupNotAvailable` when a `file_version/...` selector has\nno matching version.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/DeepLinkAccessDisabledError"
                    },
                    {
                      "$ref": "#/components/schemas/DeepLinkAccessByIdDisabledError"
                    },
                    {
                      "$ref": "#/components/schemas/DeepLinkAccessByColumnDisabledError"
                    },
                    {
                      "$ref": "#/components/schemas/ApiObjectPathError"
                    },
                    {
                      "$ref": "#/components/schemas/FileVersionNotAvailableError"
                    },
                    {
                      "$ref": "#/components/schemas/FileGroupNotAvailableError"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "The resolved object cannot be served to this caller.\n`code: ObjectInsufficientRights` when the user (the session\nuser, or the `deep_link` system user) lacks the object read\nright, or — with no `mask/\u003cname\u003e` selector — has no accessible\nmask for it;\n`code: ObjectInsufficientAssetDownloadRight` when a `file/...`\nselector resolves but the user lacks the asset-download right\nfor that file.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ObjectInsufficientRightsError"
                    },
                    {
                      "$ref": "#/components/schemas/ObjectInsufficientAssetDownloadRightError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "A `file/...` selector resolved to a file whose stored bytes are\nmissing. The response carries `code: ResourceNotFound`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "head": {
        "summary": "Probe a deep link without downloading the resource.",
        "description": "Identical resolution to `GET` (the same handler serves both\nmethods); the response carries the headers only, without the body.\n",
        "responses": {
          "200": {
            "description": "The deep link resolved successfully."
          },
          "400": {
            "description": "The request cannot be served (deep-link access disabled,\naccess-by-id / access-by-column disabled, or a malformed /\nunresolvable selector path). See the `GET` 400 for the `code`\nvalues.\n"
          },
          "403": {
            "description": "The resolved object cannot be served to this caller\n(`code: ObjectInsufficientRights` or\n`ObjectInsufficientAssetDownloadRight`). See the `GET` 403.\n"
          },
          "404": {
            "description": "A `file/...` selector resolved to a file whose stored bytes are\nmissing (`code: ResourceNotFound`).\n"
          }
        }
      }
    },
    "/tags": {
      "description": "Manages the complete set of tag groups and tags. `GET` returns every\ntaggroup and its tags and requires only an authenticated user; `POST`\nreplaces the entire set from the request body, deleting any group or tag\nabsent from it, writes the `taggroup` and `tag` tables directly in the\nrequest transaction (effective immediately, no working copy or commit\nstep), and requires the `system.tagmanager` system right.\n",
      "post": {
        "summary": "Create, update or delete taggroups and tags",
        "description": "Replaces the **entire** set of tag groups and tags. The request body is\nthe complete desired list: groups and tags present are created or\nupdated; any group or tag currently in the database but **absent** from\nthe request is deleted. The change is written directly to the `taggroup`\nand `tag` tables in the request transaction and is effective immediately;\nthere is no working copy and no separate commit step. Deletions of\nstill-referenced tags either return a `202` (auto-removable contexts,\nconfirm with `delete_policy=remove_tags`) or a `400 TagsInUse` (must be\nresolved manually first). Changing a tag's `_acl` re-validates affected\ncollection objects; if that re-validation exceeds the time limit a `202`\nis returned offering to run it in the background (confirm with\n`background_invalid_acl=true`). Requires the `system.tagmanager` system\nright. Rejected with `400 ReadOnlyMode` while the server is in read-only\nmode.\n\nDiffers from easydb 5: deleting a still-referenced tag is confirmed with\n`delete_policy=remove_tags` (auto-removable contexts) or rejected with\n`400 TagsInUse` (manual-resolution contexts), and the collection-ACL\nre-validation is confirmed with `background_invalid_acl`. easydb 5\ndocuments neither a `delete_policy` nor a `TagsInUse` error; its only\ndocumented confirmation parameter for this save is\n`collection_rights_policy`.\n",
        "tags": [
          "tags"
        ],
        "parameters": [
          {
            "name": "delete_policy",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "remove_tags"
              ]
            },
            "description": "Confirmation flag for deleting tags that are still referenced only in\ncontexts where **fylr** can clean them up automatically\n(`collection.create_object`, `objecttype_tag`, `pool_tag`). The only\nrecognized value is `remove_tags`. Without it, such a deletion returns\n`202` asking for confirmation; resend the identical request with\n`delete_policy=remove_tags` to proceed (the tag is removed from those\ncontexts and deleted). It has no effect on tags referenced in\nmanual-resolution contexts (records, ACLs, column/mask filters,\nworkflows, right presets, baseconfig), which always return\n`400 TagsInUse`.\n"
          },
          {
            "name": "background_invalid_acl",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Confirmation flag for the collection re-validation that runs when a\ntag's `_acl` changes. If the synchronous re-validation of the\naffected collection objects exceeds the time limit, the request\nreturns a `202` asking for confirmation; resend the identical request\nwith `background_invalid_acl=true` to apply the change immediately and\nschedule the re-validation as a background index job instead.\n"
          },
          {
            "name": "background_invalid_acl_timelimit",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Overrides the time limit for the synchronous collection re-validation\n(a Go duration string such as `30s`). When the limit is exceeded a\n`202` is returned; see `background_invalid_acl`.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TagGroup"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success"
          },
          "202": {
            "description": "Request must be resent and confirmed. Two situations produce this response:\n\n- One or more tags that would be deleted are still referenced in places where they can be cleaned up automatically (`collection.create_object`, `objecttype_tag`, `pool_tag`), but an explicit confirmation is required. Resend the identical request with the query parameter `delete_policy=remove_tags` to confirm.\n- A changed tag `_acl` triggered collection re-validation that exceeded the time limit. Resend the identical request with `background_invalid_acl=true` to apply the change and run the re-validation in the background.\n\nThe `tasks[].buttons[].name`/`value` of the returned payload name the query parameter to resend with.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagsPost202"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field identifies which\nvalidation rejected the request. Codes include `TagsInUse` (a tag to\nbe deleted is still referenced in a manual-resolution context),\n`ReadOnlyMode` (server in read-only mode), the rights-validation codes\nraised while checking each tag's `_acl` (`UnknownRight`,\n`UnknownRightParam`, `UnknownRightValue`, `ChoiceNotUnique`, …), and\n`ServerGeneric` for a malformed body or an unknown taggroup `type`\n(only `checkbox` and `choice` are accepted).\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/TagsInUseError"
                    },
                    {
                      "$ref": "#/components/schemas/ReadOnlyModeError"
                    },
                    {
                      "$ref": "#/components/schemas/UnknownRightError"
                    },
                    {
                      "$ref": "#/components/schemas/UnknownRightParamError"
                    },
                    {
                      "$ref": "#/components/schemas/UnknownRightValueError"
                    },
                    {
                      "$ref": "#/components/schemas/ChoiceNotUniqueError"
                    },
                    {
                      "$ref": "#/components/schemas/ServerGenericError"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.tagmanager` system right\n(and is not `system.root`). Error `code` is `SystemRightRequired`.\n\nDiffers from easydb 5: a missing system right is reported as `403`\n(`SystemRightRequired`); easydb 5 documents the missing-right case on\nthis endpoint as a `400` (\"No System Right\").\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n\nDiffers from easydb 5: a missing/invalid session is reported as `401`\n(`UserRequired`); easydb 5 documents the unauthenticated case on this\nendpoint as a `400` (\"Not Authenticated\").\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Get all tags",
        "tags": [
          "tags"
        ],
        "description": "This endpoint returns all available taggroups and tags.\n",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagGroup"
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n\nDiffers from easydb 5: a missing/invalid session is reported as `401`\n(`UserRequired`); easydb 5 documents the unauthenticated case on this\nendpoint as a `400` (\"Not Authenticated\").\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/task": {
      "x-path": "/task",
      "description": "Use this endpoint to store \u0026 retrieve tasks. A task is a configuration to\nrun a task module with pre-configured parameters. The tasks are executed in\nthe background. Tasks can be scheduled to run periodically.\n\nTasks are user specific. Like exports, tasks are run under as the user who created the task. When listing tasks, only the creating user can see his tasks.\n\nEvery task operation requires the system right `system.task` (a\n`system.root` user is also accepted). An unauthenticated request returns\n`401` with code `UserRequired`; an authenticated user lacking `system.task`\n(and not `system.root`) returns `403` with code `SystemRightRequired`.\nThe id-addressed operations `GET /task/{taskId}/log`,\n`POST /task/{taskId}/cancel` and `DELETE /task/{taskId}` load the task by\nid and then reject a caller who is neither the task's owner nor a\n`system.root` user with `403` code `InsufficientRights`. The list and\n`GET /task/{taskId}` instead filter by the session user, so another\nuser's tasks are simply not returned (an unknown id yields `404`).\n",
      "get": {
        "parameters": [
          {
            "name": "offset",
            "in": "query",
            "description": "Request the given `offset` of the log.",
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Request using the given `limit`. Default is 100.",
            "schema": {
              "type": "number",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Retrieve a list of tasks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "limit": {
                      "type": "number",
                      "format": "int64",
                      "description": "The limit of the request.\n"
                    },
                    "offset": {
                      "type": "number",
                      "format": "int64",
                      "description": "The offset of the request.\n"
                    },
                    "count": {
                      "type": "number",
                      "format": "int64",
                      "description": "The total count of the tasks of the session user.\n"
                    },
                    "objects": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "_basetype": {
                            "type": "string",
                            "enum": [
                              "task"
                            ]
                          },
                          "created_at": {
                            "type": "string",
                            "format": "datetime",
                            "description": "UTC time of when the task was created.\n"
                          },
                          "updated_at": {
                            "type": "string",
                            "format": "datetime",
                            "description": "UTC time of when the task was updated.\n"
                          },
                          "task": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "number",
                                "format": "int64",
                                "description": "ID of the task. This is issued by the server.\n"
                              },
                              "_version": {
                                "type": "number",
                                "format": "int64",
                                "description": "Version of the task. The version must be incremented when saving a new\nversion of the task. While the task is running, the server may perform\nupdates on the task object without incrementing the version.\n"
                              },
                              "task_module": {
                                "type": "string",
                                "description": "Name of the task module to run the task. Retrieve a list with `/api/v1/task/modules`.\n"
                              },
                              "task_params": {
                                "type": "object",
                                "additionalProperties": true,
                                "description": "The task properties. The schema for this is defined by the task module.\n"
                              },
                              "task_timeout_sec": {
                                "type": "number",
                                "format": "int",
                                "description": "When the task is run, this timeout is set. In case of a timeout the task will be in state `error`. Use `0` for no timeout.\n"
                              },
                              "description": {
                                "type": "string",
                                "description": "A user provided description of the task.\n"
                              },
                              "next_run_at": {
                                "type": "string",
                                "format": "datetime",
                                "description": "The UTC time when the task will be started. It is possible that the task is run later that the given time (if other tasks are currently running), but not before. Set this to `null` to not execute this task. If a task is scheduled, the scheduler will update this property after the task has run.\n"
                              },
                              "frontend_prefs": {
                                "type": "object",
                                "additionalProperties": true,
                                "description": "Provided by API using Apps. The top level key of the map should reflect the name of your App. Apps are required to store unknown keys (and data) along with their own contribution.\n"
                              },
                              "email": {
                                "type": "object",
                                "properties": {
                                  "recipients": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "email": {
                                          "type": "string",
                                          "format": "email",
                                          "description": "The email address of the recipient. Mails are send using the `To:` email header.\n"
                                        },
                                        "problems_only": {
                                          "type": "boolean",
                                          "description": "If set, emails are only sent if the task finished with a state other than `done`.\n"
                                        }
                                      }
                                    }
                                  }
                                }
                              },
                              "schedules": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "description": "A schedule sets criterias to repeatedly start task or jobs. All defined criterias need to be met in order for a schedule to run.\n",
                                  "properties": {
                                    "days_of_month": {
                                      "type": "array",
                                      "items": {
                                        "type": "number",
                                        "format": "int",
                                        "description": "The day of the month when this schedule should run.\n"
                                      }
                                    },
                                    "weekdays": {
                                      "type": "array",
                                      "items": {
                                        "type": "string",
                                        "enum": [
                                          "sunday",
                                          "monday",
                                          "tuesday",
                                          "wednesday",
                                          "thursday",
                                          "friday",
                                          "saturday"
                                        ]
                                      },
                                      "description": "The weekday when this schedule should run.\n"
                                    },
                                    "hours": {
                                      "type": "array",
                                      "items": {
                                        "type": "number",
                                        "format": "int",
                                        "description": "The hour when this schedule should run. Range `0`-`23`.\n"
                                      }
                                    },
                                    "minutes": {
                                      "type": "array",
                                      "items": {
                                        "type": "number",
                                        "format": "int",
                                        "description": "The minute when this schedule should run. Range `0`-`59`.\n"
                                      }
                                    },
                                    "timezone": {
                                      "type": "string",
                                      "description": "The timezone this schedule should be run in. Valid names are in [IANA format](https://www.iana.org/time-zones).\n"
                                    }
                                  }
                                }
                              },
                              "state": {
                                "type": "object",
                                "readOnly": true,
                                "additionalProperties": true,
                                "description": "Stores the state of a task. This can be used by the task module to continue interrupted work or otherwise. The data is provided over the API, so frontends may use it.\n"
                              },
                              "status": {
                                "type": "string",
                                "readOnly": true,
                                "enum": [
                                  "new",
                                  "running",
                                  "done",
                                  "canceled",
                                  "error"
                                ],
                                "description": "`status` is set by the **fylr** task runner.\n"
                              },
                              "status_percent": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "readOnly": true,
                                "format": "int",
                                "minimum": 0,
                                "maximum": 100,
                                "description": "If supported by the task runner, a number from `0` to `100` (percent) indicating the progress of a task in state `running`. This can be `null` if the task module has not started updating this yet, or it is not supported by the task module. Frontends should only show and use this if it is not `null`.\n"
                              },
                              "status_msg": {
                                "type": "string",
                                "readOnly": true,
                                "description": "If the status is `error` or `canceled`, the status message gives more information.\n"
                              },
                              "run_started_at": {
                                "type": "string",
                                "format": "datetime",
                                "readOnly": true,
                                "description": "UTC time when the last run of the task was started. It is set to `null` when the task re-starts.\n"
                              },
                              "run_canceled_at": {
                                "type": "string",
                                "format": "datetime",
                                "readOnly": true,
                                "description": "UTC time when the last run of the task was canceled. It is set to `null` when the task re-starts.\n"
                              },
                              "run_finished_at": {
                                "type": "string",
                                "format": "datetime",
                                "readOnly": true,
                                "description": "UTC time when the last run of the task has finished. It is set to `null` when the task re-starts.\n"
                              }
                            }
                          },
                          "_user": {
                            "type": "object",
                            "readOnly": true,
                            "description": "The user that created the task. The task is run as this user. This is a\nflat user object; only the creating user (or a `system.root` user) can\nretrieve the task.\n",
                            "properties": {
                              "_id": {
                                "type": "number",
                                "format": "int64",
                                "description": "The id of the user. It is automatically assigned.\n"
                              },
                              "_version": {
                                "type": "number",
                                "format": "int64",
                                "description": "The version of the user record.\n"
                              },
                              "_generated_displayname": {
                                "type": "string",
                                "description": "The generated displayname of the user. This uses `login` and `email`.\n"
                              }
                            }
                          }
                        },
                        "example": {
                          "task": {
                            "_id": 1,
                            "_version": 2,
                            "task_module": "sleep",
                            "description": "henk is super",
                            "task_params": {
                              "runtime": 5
                            },
                            "task_timeout_sec": 100,
                            "next_run_at": "2026-05-30T12:00:10Z",
                            "status": "new"
                          },
                          "_user": {
                            "_generated_displayname": "root"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.task` system right (and is\nnot `system.root`). Raised with code `SystemRightRequired`\n(`parameters.rights` lists the rights that would have satisfied the\ncheck).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "put": {
        "description": "Create a new task.\n",
        "parameters": [
          {
            "name": "confirm",
            "in": "query",
            "description": "Some task modules answer an unconfirmed save with `202` and a\nconfirmation dialog instead of creating the task (currently\n`consolidate_objects`: the preview reports how many records\nreference the sources and how many of those the saving user is\nallowed to re-link). Repeat the request with `confirm=yes` (the\nconfirm key/value of the dialog's button) to create the task.\n",
            "schema": {
              "type": "string",
              "enum": [
                "yes"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "_basetype": {
                    "type": "string",
                    "enum": [
                      "task"
                    ]
                  },
                  "created_at": {
                    "type": "string",
                    "format": "datetime",
                    "description": "UTC time of when the task was created.\n"
                  },
                  "updated_at": {
                    "type": "string",
                    "format": "datetime",
                    "description": "UTC time of when the task was updated.\n"
                  },
                  "task": {
                    "type": "object",
                    "properties": {
                      "_id": {
                        "type": "number",
                        "format": "int64",
                        "description": "ID of the task. This is issued by the server.\n"
                      },
                      "_version": {
                        "type": "number",
                        "format": "int64",
                        "description": "Version of the task. The version must be incremented when saving a new\nversion of the task. While the task is running, the server may perform\nupdates on the task object without incrementing the version.\n"
                      },
                      "task_module": {
                        "type": "string",
                        "description": "Name of the task module to run the task. Retrieve a list with `/api/v1/task/modules`.\n"
                      },
                      "task_params": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "The task properties. The schema for this is defined by the task module.\n"
                      },
                      "task_timeout_sec": {
                        "type": "number",
                        "format": "int",
                        "description": "When the task is run, this timeout is set. In case of a timeout the task will be in state `error`. Use `0` for no timeout.\n"
                      },
                      "description": {
                        "type": "string",
                        "description": "A user provided description of the task.\n"
                      },
                      "next_run_at": {
                        "type": "string",
                        "format": "datetime",
                        "description": "The UTC time when the task will be started. It is possible that the task is run later that the given time (if other tasks are currently running), but not before. Set this to `null` to not execute this task. If a task is scheduled, the scheduler will update this property after the task has run.\n"
                      },
                      "frontend_prefs": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "Provided by API using Apps. The top level key of the map should reflect the name of your App. Apps are required to store unknown keys (and data) along with their own contribution.\n"
                      },
                      "email": {
                        "type": "object",
                        "properties": {
                          "recipients": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "email": {
                                  "type": "string",
                                  "format": "email",
                                  "description": "The email address of the recipient. Mails are send using the `To:` email header.\n"
                                },
                                "problems_only": {
                                  "type": "boolean",
                                  "description": "If set, emails are only sent if the task finished with a state other than `done`.\n"
                                }
                              }
                            }
                          }
                        }
                      },
                      "schedules": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "A schedule sets criterias to repeatedly start task or jobs. All defined criterias need to be met in order for a schedule to run.\n",
                          "properties": {
                            "days_of_month": {
                              "type": "array",
                              "items": {
                                "type": "number",
                                "format": "int",
                                "description": "The day of the month when this schedule should run.\n"
                              }
                            },
                            "weekdays": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "sunday",
                                  "monday",
                                  "tuesday",
                                  "wednesday",
                                  "thursday",
                                  "friday",
                                  "saturday"
                                ]
                              },
                              "description": "The weekday when this schedule should run.\n"
                            },
                            "hours": {
                              "type": "array",
                              "items": {
                                "type": "number",
                                "format": "int",
                                "description": "The hour when this schedule should run. Range `0`-`23`.\n"
                              }
                            },
                            "minutes": {
                              "type": "array",
                              "items": {
                                "type": "number",
                                "format": "int",
                                "description": "The minute when this schedule should run. Range `0`-`59`.\n"
                              }
                            },
                            "timezone": {
                              "type": "string",
                              "description": "The timezone this schedule should be run in. Valid names are in [IANA format](https://www.iana.org/time-zones).\n"
                            }
                          }
                        }
                      },
                      "state": {
                        "type": "object",
                        "readOnly": true,
                        "additionalProperties": true,
                        "description": "Stores the state of a task. This can be used by the task module to continue interrupted work or otherwise. The data is provided over the API, so frontends may use it.\n"
                      },
                      "status": {
                        "type": "string",
                        "readOnly": true,
                        "enum": [
                          "new",
                          "running",
                          "done",
                          "canceled",
                          "error"
                        ],
                        "description": "`status` is set by the **fylr** task runner.\n"
                      },
                      "status_percent": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "readOnly": true,
                        "format": "int",
                        "minimum": 0,
                        "maximum": 100,
                        "description": "If supported by the task runner, a number from `0` to `100` (percent) indicating the progress of a task in state `running`. This can be `null` if the task module has not started updating this yet, or it is not supported by the task module. Frontends should only show and use this if it is not `null`.\n"
                      },
                      "status_msg": {
                        "type": "string",
                        "readOnly": true,
                        "description": "If the status is `error` or `canceled`, the status message gives more information.\n"
                      },
                      "run_started_at": {
                        "type": "string",
                        "format": "datetime",
                        "readOnly": true,
                        "description": "UTC time when the last run of the task was started. It is set to `null` when the task re-starts.\n"
                      },
                      "run_canceled_at": {
                        "type": "string",
                        "format": "datetime",
                        "readOnly": true,
                        "description": "UTC time when the last run of the task was canceled. It is set to `null` when the task re-starts.\n"
                      },
                      "run_finished_at": {
                        "type": "string",
                        "format": "datetime",
                        "readOnly": true,
                        "description": "UTC time when the last run of the task has finished. It is set to `null` when the task re-starts.\n"
                      }
                    }
                  },
                  "_user": {
                    "type": "object",
                    "readOnly": true,
                    "description": "The user that created the task. The task is run as this user. This is a\nflat user object; only the creating user (or a `system.root` user) can\nretrieve the task.\n",
                    "properties": {
                      "_id": {
                        "type": "number",
                        "format": "int64",
                        "description": "The id of the user. It is automatically assigned.\n"
                      },
                      "_version": {
                        "type": "number",
                        "format": "int64",
                        "description": "The version of the user record.\n"
                      },
                      "_generated_displayname": {
                        "type": "string",
                        "description": "The generated displayname of the user. This uses `login` and `email`.\n"
                      }
                    }
                  }
                },
                "example": {
                  "task": {
                    "_id": 1,
                    "_version": 2,
                    "task_module": "sleep",
                    "description": "henk is super",
                    "task_params": {
                      "runtime": 5
                    },
                    "task_timeout_sec": 100,
                    "next_run_at": "2026-05-30T12:00:10Z",
                    "status": "new"
                  },
                  "_user": {
                    "_generated_displayname": "root"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created a new task."
          },
          "202": {
            "description": "The task module asks for a confirmation instead of creating the\ntask: `tasks` carries title, localized message, machine-readable\n`data` and buttons; the button's `name`/`value` pair is repeated\nas a query parameter (`confirm=yes`) to confirm.\n`consolidate_objects` also answers a target-less unconfirmed save\nwith this preview (`data`: `references`, `relink`, `denied`,\n`capped`) — such a probe can never create a task, a confirmed\nsave requires a valid target.\n"
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the response\nidentifies the specific validation failure.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModuleUnknownError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.task` system right (and is\nnot `system.root`). Raised with code `SystemRightRequired`\n(`parameters.rights` lists the rights that would have satisfied the\ncheck).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      },
      "post": {
        "description": "Create a new task.\n",
        "parameters": [
          {
            "name": "confirm",
            "in": "query",
            "description": "Some task modules answer an unconfirmed save with `202` and a\nconfirmation dialog instead of creating the task (currently\n`consolidate_objects`: the preview reports how many records\nreference the sources and how many of those the saving user is\nallowed to re-link). Repeat the request with `confirm=yes` (the\nconfirm key/value of the dialog's button) to create the task.\n",
            "schema": {
              "type": "string",
              "enum": [
                "yes"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "_basetype": {
                    "type": "string",
                    "enum": [
                      "task"
                    ]
                  },
                  "created_at": {
                    "type": "string",
                    "format": "datetime",
                    "description": "UTC time of when the task was created.\n"
                  },
                  "updated_at": {
                    "type": "string",
                    "format": "datetime",
                    "description": "UTC time of when the task was updated.\n"
                  },
                  "task": {
                    "type": "object",
                    "properties": {
                      "_id": {
                        "type": "number",
                        "format": "int64",
                        "description": "ID of the task. This is issued by the server.\n"
                      },
                      "_version": {
                        "type": "number",
                        "format": "int64",
                        "description": "Version of the task. The version must be incremented when saving a new\nversion of the task. While the task is running, the server may perform\nupdates on the task object without incrementing the version.\n"
                      },
                      "task_module": {
                        "type": "string",
                        "description": "Name of the task module to run the task. Retrieve a list with `/api/v1/task/modules`.\n"
                      },
                      "task_params": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "The task properties. The schema for this is defined by the task module.\n"
                      },
                      "task_timeout_sec": {
                        "type": "number",
                        "format": "int",
                        "description": "When the task is run, this timeout is set. In case of a timeout the task will be in state `error`. Use `0` for no timeout.\n"
                      },
                      "description": {
                        "type": "string",
                        "description": "A user provided description of the task.\n"
                      },
                      "next_run_at": {
                        "type": "string",
                        "format": "datetime",
                        "description": "The UTC time when the task will be started. It is possible that the task is run later that the given time (if other tasks are currently running), but not before. Set this to `null` to not execute this task. If a task is scheduled, the scheduler will update this property after the task has run.\n"
                      },
                      "frontend_prefs": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "Provided by API using Apps. The top level key of the map should reflect the name of your App. Apps are required to store unknown keys (and data) along with their own contribution.\n"
                      },
                      "email": {
                        "type": "object",
                        "properties": {
                          "recipients": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "email": {
                                  "type": "string",
                                  "format": "email",
                                  "description": "The email address of the recipient. Mails are send using the `To:` email header.\n"
                                },
                                "problems_only": {
                                  "type": "boolean",
                                  "description": "If set, emails are only sent if the task finished with a state other than `done`.\n"
                                }
                              }
                            }
                          }
                        }
                      },
                      "schedules": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "A schedule sets criterias to repeatedly start task or jobs. All defined criterias need to be met in order for a schedule to run.\n",
                          "properties": {
                            "days_of_month": {
                              "type": "array",
                              "items": {
                                "type": "number",
                                "format": "int",
                                "description": "The day of the month when this schedule should run.\n"
                              }
                            },
                            "weekdays": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "sunday",
                                  "monday",
                                  "tuesday",
                                  "wednesday",
                                  "thursday",
                                  "friday",
                                  "saturday"
                                ]
                              },
                              "description": "The weekday when this schedule should run.\n"
                            },
                            "hours": {
                              "type": "array",
                              "items": {
                                "type": "number",
                                "format": "int",
                                "description": "The hour when this schedule should run. Range `0`-`23`.\n"
                              }
                            },
                            "minutes": {
                              "type": "array",
                              "items": {
                                "type": "number",
                                "format": "int",
                                "description": "The minute when this schedule should run. Range `0`-`59`.\n"
                              }
                            },
                            "timezone": {
                              "type": "string",
                              "description": "The timezone this schedule should be run in. Valid names are in [IANA format](https://www.iana.org/time-zones).\n"
                            }
                          }
                        }
                      },
                      "state": {
                        "type": "object",
                        "readOnly": true,
                        "additionalProperties": true,
                        "description": "Stores the state of a task. This can be used by the task module to continue interrupted work or otherwise. The data is provided over the API, so frontends may use it.\n"
                      },
                      "status": {
                        "type": "string",
                        "readOnly": true,
                        "enum": [
                          "new",
                          "running",
                          "done",
                          "canceled",
                          "error"
                        ],
                        "description": "`status` is set by the **fylr** task runner.\n"
                      },
                      "status_percent": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "readOnly": true,
                        "format": "int",
                        "minimum": 0,
                        "maximum": 100,
                        "description": "If supported by the task runner, a number from `0` to `100` (percent) indicating the progress of a task in state `running`. This can be `null` if the task module has not started updating this yet, or it is not supported by the task module. Frontends should only show and use this if it is not `null`.\n"
                      },
                      "status_msg": {
                        "type": "string",
                        "readOnly": true,
                        "description": "If the status is `error` or `canceled`, the status message gives more information.\n"
                      },
                      "run_started_at": {
                        "type": "string",
                        "format": "datetime",
                        "readOnly": true,
                        "description": "UTC time when the last run of the task was started. It is set to `null` when the task re-starts.\n"
                      },
                      "run_canceled_at": {
                        "type": "string",
                        "format": "datetime",
                        "readOnly": true,
                        "description": "UTC time when the last run of the task was canceled. It is set to `null` when the task re-starts.\n"
                      },
                      "run_finished_at": {
                        "type": "string",
                        "format": "datetime",
                        "readOnly": true,
                        "description": "UTC time when the last run of the task has finished. It is set to `null` when the task re-starts.\n"
                      }
                    }
                  },
                  "_user": {
                    "type": "object",
                    "readOnly": true,
                    "description": "The user that created the task. The task is run as this user. This is a\nflat user object; only the creating user (or a `system.root` user) can\nretrieve the task.\n",
                    "properties": {
                      "_id": {
                        "type": "number",
                        "format": "int64",
                        "description": "The id of the user. It is automatically assigned.\n"
                      },
                      "_version": {
                        "type": "number",
                        "format": "int64",
                        "description": "The version of the user record.\n"
                      },
                      "_generated_displayname": {
                        "type": "string",
                        "description": "The generated displayname of the user. This uses `login` and `email`.\n"
                      }
                    }
                  }
                },
                "example": {
                  "task": {
                    "_id": 1,
                    "_version": 2,
                    "task_module": "sleep",
                    "description": "henk is super",
                    "task_params": {
                      "runtime": 5
                    },
                    "task_timeout_sec": 100,
                    "next_run_at": "2026-05-30T12:00:10Z",
                    "status": "new"
                  },
                  "_user": {
                    "_generated_displayname": "root"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created a new task."
          },
          "202": {
            "description": "The task module asks for a confirmation instead of creating the\ntask: `tasks` carries title, localized message, machine-readable\n`data` and buttons; the button's `name`/`value` pair is repeated\nas a query parameter (`confirm=yes`) to confirm.\n`consolidate_objects` also answers a target-less unconfirmed save\nwith this preview (`data`: `references`, `relink`, `denied`,\n`capped`) — such a probe can never create a task, a confirmed\nsave requires a valid target.\n"
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the response\nidentifies the specific validation failure.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModuleUnknownError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.task` system right (and is\nnot `system.root`). Raised with code `SystemRightRequired`\n(`parameters.rights` lists the rights that would have satisfied the\ncheck).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/task/{taskId}/log": {
      "x-path": "/task",
      "description": "Access the log of a specific task.\n",
      "get": {
        "parameters": [
          {
            "name": "taskId",
            "in": "path",
            "description": "The ID of the task.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Request the given `offset` of the log.",
            "schema": {
              "type": "number",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Request using the given `limit`. Default is 100.",
            "schema": {
              "type": "number",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task runners can write log entries. This endpoint can be used to retrieve them.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "idx": {
                        "type": "number",
                        "format": "int",
                        "description": "Index of the log entry, starts at `0`.\n"
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "datetime",
                        "description": "UTC time of the entry.\n"
                      },
                      "level": {
                        "type": "string",
                        "enum": [
                          "debug",
                          "info",
                          "warning",
                          "error"
                        ],
                        "description": "Severity of the log entry.\n"
                      },
                      "msg": {
                        "type": "string",
                        "description": "Message of the log entry.\n"
                      },
                      "status_percent": {
                        "type": "number",
                        "format": "int64",
                        "description": "The current status in percent, can be `null`. If set (per task module), the task runner updates the `status_percent` of the task to the latest data.\n"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the task's creator nor a\n`system.root` user. Tasks are user-specific; only the user who\ncreated a task (or a `system.root` user) can access it. A user\nwithout the `system.task` system right also receives a `403`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/InsufficientRightsError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "No task with this id exists. The id was not loadable. Raised with\ncode `ObjectNotFound` (`parameters.object` carries a `task \u003cid\u003e`\ntoken, e.g. `task 7`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/task/{taskId}/cancel": {
      "x-path": "/task",
      "description": "Request cancellation of a task that is in status `running`. Cancelling a\ntask in any other status, or one for which cancellation was already\nrequested, is rejected with a `400`.\n",
      "post": {
        "parameters": [
          {
            "name": "taskId",
            "in": "path",
            "description": "The ID of the task.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancellation was requested: the task's `run_canceled_at` timestamp\nis set (and its `_version` is incremented). The task runner watches\nfor this flag and stops the running task as soon as possible; the\nrunner — not this request — is what eventually moves the task to\n`status` `canceled`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  },
                  "example": {
                    "status": {
                      "acknowledged": "ok"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the response\nidentifies the specific validation failure.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModuleUnknownError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the task's creator nor a\n`system.root` user. Tasks are user-specific; only the user who\ncreated a task (or a `system.root` user) can access it. A user\nwithout the `system.task` system right also receives a `403`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/InsufficientRightsError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "No task with this id exists. The id was not loadable. Raised with\ncode `ObjectNotFound` (`parameters.object` carries a `task \u003cid\u003e`\ntoken, e.g. `task 7`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      }
    },
    "/task/{taskId}": {
      "x-path": "/task",
      "description": "Access a single task by ID.\n",
      "delete": {
        "description": "Delete a task. A task in status `running` cannot be deleted (cancel it\nfirst); attempting to do so is rejected with a `400`.\n",
        "parameters": [
          {
            "name": "taskId",
            "in": "path",
            "description": "The ID of the task.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The task was successfully deleted.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "object",
                      "properties": {
                        "acknowledged": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ]
                        }
                      }
                    }
                  },
                  "example": {
                    "status": {
                      "acknowledged": "ok"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the response\nidentifies the specific validation failure.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModuleUnknownError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user is neither the task's creator nor a\n`system.root` user. Tasks are user-specific; only the user who\ncreated a task (or a `system.root` user) can access it. A user\nwithout the `system.task` system right also receives a `403`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SystemRightRequiredError"
                    },
                    {
                      "$ref": "#/components/schemas/InsufficientRightsError"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "No task with this id exists. The id was not loadable. Raised with\ncode `ObjectNotFound` (`parameters.object` carries a `task \u003cid\u003e`\ntoken, e.g. `task 7`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectNotFoundError"
                }
              }
            }
          }
        }
      },
      "get": {
        "parameters": [
          {
            "name": "taskId",
            "in": "path",
            "description": "The ID of the task.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The task.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_basetype": {
                      "type": "string",
                      "enum": [
                        "task"
                      ]
                    },
                    "created_at": {
                      "type": "string",
                      "format": "datetime",
                      "description": "UTC time of when the task was created.\n"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "datetime",
                      "description": "UTC time of when the task was updated.\n"
                    },
                    "task": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "description": "ID of the task. This is issued by the server.\n"
                        },
                        "_version": {
                          "type": "number",
                          "format": "int64",
                          "description": "Version of the task. The version must be incremented when saving a new\nversion of the task. While the task is running, the server may perform\nupdates on the task object without incrementing the version.\n"
                        },
                        "task_module": {
                          "type": "string",
                          "description": "Name of the task module to run the task. Retrieve a list with `/api/v1/task/modules`.\n"
                        },
                        "task_params": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "The task properties. The schema for this is defined by the task module.\n"
                        },
                        "task_timeout_sec": {
                          "type": "number",
                          "format": "int",
                          "description": "When the task is run, this timeout is set. In case of a timeout the task will be in state `error`. Use `0` for no timeout.\n"
                        },
                        "description": {
                          "type": "string",
                          "description": "A user provided description of the task.\n"
                        },
                        "next_run_at": {
                          "type": "string",
                          "format": "datetime",
                          "description": "The UTC time when the task will be started. It is possible that the task is run later that the given time (if other tasks are currently running), but not before. Set this to `null` to not execute this task. If a task is scheduled, the scheduler will update this property after the task has run.\n"
                        },
                        "frontend_prefs": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Provided by API using Apps. The top level key of the map should reflect the name of your App. Apps are required to store unknown keys (and data) along with their own contribution.\n"
                        },
                        "email": {
                          "type": "object",
                          "properties": {
                            "recipients": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "email": {
                                    "type": "string",
                                    "format": "email",
                                    "description": "The email address of the recipient. Mails are send using the `To:` email header.\n"
                                  },
                                  "problems_only": {
                                    "type": "boolean",
                                    "description": "If set, emails are only sent if the task finished with a state other than `done`.\n"
                                  }
                                }
                              }
                            }
                          }
                        },
                        "schedules": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "description": "A schedule sets criterias to repeatedly start task or jobs. All defined criterias need to be met in order for a schedule to run.\n",
                            "properties": {
                              "days_of_month": {
                                "type": "array",
                                "items": {
                                  "type": "number",
                                  "format": "int",
                                  "description": "The day of the month when this schedule should run.\n"
                                }
                              },
                              "weekdays": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "sunday",
                                    "monday",
                                    "tuesday",
                                    "wednesday",
                                    "thursday",
                                    "friday",
                                    "saturday"
                                  ]
                                },
                                "description": "The weekday when this schedule should run.\n"
                              },
                              "hours": {
                                "type": "array",
                                "items": {
                                  "type": "number",
                                  "format": "int",
                                  "description": "The hour when this schedule should run. Range `0`-`23`.\n"
                                }
                              },
                              "minutes": {
                                "type": "array",
                                "items": {
                                  "type": "number",
                                  "format": "int",
                                  "description": "The minute when this schedule should run. Range `0`-`59`.\n"
                                }
                              },
                              "timezone": {
                                "type": "string",
                                "description": "The timezone this schedule should be run in. Valid names are in [IANA format](https://www.iana.org/time-zones).\n"
                              }
                            }
                          }
                        },
                        "state": {
                          "type": "object",
                          "readOnly": true,
                          "additionalProperties": true,
                          "description": "Stores the state of a task. This can be used by the task module to continue interrupted work or otherwise. The data is provided over the API, so frontends may use it.\n"
                        },
                        "status": {
                          "type": "string",
                          "readOnly": true,
                          "enum": [
                            "new",
                            "running",
                            "done",
                            "canceled",
                            "error"
                          ],
                          "description": "`status` is set by the **fylr** task runner.\n"
                        },
                        "status_percent": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "readOnly": true,
                          "format": "int",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "If supported by the task runner, a number from `0` to `100` (percent) indicating the progress of a task in state `running`. This can be `null` if the task module has not started updating this yet, or it is not supported by the task module. Frontends should only show and use this if it is not `null`.\n"
                        },
                        "status_msg": {
                          "type": "string",
                          "readOnly": true,
                          "description": "If the status is `error` or `canceled`, the status message gives more information.\n"
                        },
                        "run_started_at": {
                          "type": "string",
                          "format": "datetime",
                          "readOnly": true,
                          "description": "UTC time when the last run of the task was started. It is set to `null` when the task re-starts.\n"
                        },
                        "run_canceled_at": {
                          "type": "string",
                          "format": "datetime",
                          "readOnly": true,
                          "description": "UTC time when the last run of the task was canceled. It is set to `null` when the task re-starts.\n"
                        },
                        "run_finished_at": {
                          "type": "string",
                          "format": "datetime",
                          "readOnly": true,
                          "description": "UTC time when the last run of the task has finished. It is set to `null` when the task re-starts.\n"
                        }
                      }
                    },
                    "_user": {
                      "type": "object",
                      "readOnly": true,
                      "description": "The user that created the task. The task is run as this user. This is a\nflat user object; only the creating user (or a `system.root` user) can\nretrieve the task.\n",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "description": "The id of the user. It is automatically assigned.\n"
                        },
                        "_version": {
                          "type": "number",
                          "format": "int64",
                          "description": "The version of the user record.\n"
                        },
                        "_generated_displayname": {
                          "type": "string",
                          "description": "The generated displayname of the user. This uses `login` and `email`.\n"
                        }
                      }
                    }
                  },
                  "example": {
                    "task": {
                      "_id": 1,
                      "_version": 2,
                      "task_module": "sleep",
                      "description": "henk is super",
                      "task_params": {
                        "runtime": 5
                      },
                      "task_timeout_sec": 100,
                      "next_run_at": "2026-05-30T12:00:10Z",
                      "status": "new"
                    },
                    "_user": {
                      "_generated_displayname": "root"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.task` system right (and is\nnot `system.root`). Raised with code `SystemRightRequired`\n(`parameters.rights` lists the rights that would have satisfied the\ncheck).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          },
          "404": {
            "description": "No task with this id exists for the authenticated user. The\n`GET /task/{taskId}` operation raises code `ResourceNotFound`\n(`parameters.resource` carries a `task \u003cid\u003e` token).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceNotFoundError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "description": "Update a task. A task can only be updated if it is not in status\n`running`. The body must carry `_version` one higher than the stored\nversion; a mismatch is rejected with code `VersionMismatch`. The task's\nowner (`_user`) is preserved and cannot be reassigned; ownership is not\nre-checked on update (any holder of `system.task` may patch any task).\nUpdating a task whose id does not exist is reported as a `400`, not a\n`404`.\n",
        "parameters": [
          {
            "name": "taskId",
            "in": "path",
            "description": "The ID of the task.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The patched task.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "_basetype": {
                      "type": "string",
                      "enum": [
                        "task"
                      ]
                    },
                    "created_at": {
                      "type": "string",
                      "format": "datetime",
                      "description": "UTC time of when the task was created.\n"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "datetime",
                      "description": "UTC time of when the task was updated.\n"
                    },
                    "task": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "description": "ID of the task. This is issued by the server.\n"
                        },
                        "_version": {
                          "type": "number",
                          "format": "int64",
                          "description": "Version of the task. The version must be incremented when saving a new\nversion of the task. While the task is running, the server may perform\nupdates on the task object without incrementing the version.\n"
                        },
                        "task_module": {
                          "type": "string",
                          "description": "Name of the task module to run the task. Retrieve a list with `/api/v1/task/modules`.\n"
                        },
                        "task_params": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "The task properties. The schema for this is defined by the task module.\n"
                        },
                        "task_timeout_sec": {
                          "type": "number",
                          "format": "int",
                          "description": "When the task is run, this timeout is set. In case of a timeout the task will be in state `error`. Use `0` for no timeout.\n"
                        },
                        "description": {
                          "type": "string",
                          "description": "A user provided description of the task.\n"
                        },
                        "next_run_at": {
                          "type": "string",
                          "format": "datetime",
                          "description": "The UTC time when the task will be started. It is possible that the task is run later that the given time (if other tasks are currently running), but not before. Set this to `null` to not execute this task. If a task is scheduled, the scheduler will update this property after the task has run.\n"
                        },
                        "frontend_prefs": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Provided by API using Apps. The top level key of the map should reflect the name of your App. Apps are required to store unknown keys (and data) along with their own contribution.\n"
                        },
                        "email": {
                          "type": "object",
                          "properties": {
                            "recipients": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "email": {
                                    "type": "string",
                                    "format": "email",
                                    "description": "The email address of the recipient. Mails are send using the `To:` email header.\n"
                                  },
                                  "problems_only": {
                                    "type": "boolean",
                                    "description": "If set, emails are only sent if the task finished with a state other than `done`.\n"
                                  }
                                }
                              }
                            }
                          }
                        },
                        "schedules": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "description": "A schedule sets criterias to repeatedly start task or jobs. All defined criterias need to be met in order for a schedule to run.\n",
                            "properties": {
                              "days_of_month": {
                                "type": "array",
                                "items": {
                                  "type": "number",
                                  "format": "int",
                                  "description": "The day of the month when this schedule should run.\n"
                                }
                              },
                              "weekdays": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "sunday",
                                    "monday",
                                    "tuesday",
                                    "wednesday",
                                    "thursday",
                                    "friday",
                                    "saturday"
                                  ]
                                },
                                "description": "The weekday when this schedule should run.\n"
                              },
                              "hours": {
                                "type": "array",
                                "items": {
                                  "type": "number",
                                  "format": "int",
                                  "description": "The hour when this schedule should run. Range `0`-`23`.\n"
                                }
                              },
                              "minutes": {
                                "type": "array",
                                "items": {
                                  "type": "number",
                                  "format": "int",
                                  "description": "The minute when this schedule should run. Range `0`-`59`.\n"
                                }
                              },
                              "timezone": {
                                "type": "string",
                                "description": "The timezone this schedule should be run in. Valid names are in [IANA format](https://www.iana.org/time-zones).\n"
                              }
                            }
                          }
                        },
                        "state": {
                          "type": "object",
                          "readOnly": true,
                          "additionalProperties": true,
                          "description": "Stores the state of a task. This can be used by the task module to continue interrupted work or otherwise. The data is provided over the API, so frontends may use it.\n"
                        },
                        "status": {
                          "type": "string",
                          "readOnly": true,
                          "enum": [
                            "new",
                            "running",
                            "done",
                            "canceled",
                            "error"
                          ],
                          "description": "`status` is set by the **fylr** task runner.\n"
                        },
                        "status_percent": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "readOnly": true,
                          "format": "int",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "If supported by the task runner, a number from `0` to `100` (percent) indicating the progress of a task in state `running`. This can be `null` if the task module has not started updating this yet, or it is not supported by the task module. Frontends should only show and use this if it is not `null`.\n"
                        },
                        "status_msg": {
                          "type": "string",
                          "readOnly": true,
                          "description": "If the status is `error` or `canceled`, the status message gives more information.\n"
                        },
                        "run_started_at": {
                          "type": "string",
                          "format": "datetime",
                          "readOnly": true,
                          "description": "UTC time when the last run of the task was started. It is set to `null` when the task re-starts.\n"
                        },
                        "run_canceled_at": {
                          "type": "string",
                          "format": "datetime",
                          "readOnly": true,
                          "description": "UTC time when the last run of the task was canceled. It is set to `null` when the task re-starts.\n"
                        },
                        "run_finished_at": {
                          "type": "string",
                          "format": "datetime",
                          "readOnly": true,
                          "description": "UTC time when the last run of the task has finished. It is set to `null` when the task re-starts.\n"
                        }
                      }
                    },
                    "_user": {
                      "type": "object",
                      "readOnly": true,
                      "description": "The user that created the task. The task is run as this user. This is a\nflat user object; only the creating user (or a `system.root` user) can\nretrieve the task.\n",
                      "properties": {
                        "_id": {
                          "type": "number",
                          "format": "int64",
                          "description": "The id of the user. It is automatically assigned.\n"
                        },
                        "_version": {
                          "type": "number",
                          "format": "int64",
                          "description": "The version of the user record.\n"
                        },
                        "_generated_displayname": {
                          "type": "string",
                          "description": "The generated displayname of the user. This uses `login` and `email`.\n"
                        }
                      }
                    }
                  },
                  "example": {
                    "task": {
                      "_id": 1,
                      "_version": 2,
                      "task_module": "sleep",
                      "description": "henk is super",
                      "task_params": {
                        "runtime": 5
                      },
                      "task_timeout_sec": 100,
                      "next_run_at": "2026-05-30T12:00:10Z",
                      "status": "new"
                    },
                    "_user": {
                      "_generated_displayname": "root"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be processed. The `code` field of the response\nidentifies the specific validation failure.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModuleUnknownError"
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.task` system right (and is\nnot `system.root`). Raised with code `SystemRightRequired`\n(`parameters.rights` lists the rights that would have satisfied the\ncheck).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/task/modules": {
      "x-path": "/task",
      "description": "List the available task modules. Each entry reports a module `name` (the\nvalue a task references to select its runner), a localised `displayname`\nand `description`, a `debug` flag, and the `params` definition describing\nthe parameters that module accepts.\n\nThe modules are built into **fylr**, they cannot be added by plugins. The\n`task_params` of a task must match the `params` definition of its module:\n\n### `consolidate_objects`\n\nRe-links all references to the source objects to one target object, then\ndeletes the sources. Use this to merge duplicate linked objects (e.g.\nkeywords, actors, places). Bidirectional links are honored: re-pointing\none updates the mirrored entry on the target and removes the stale\nmirror from a source that is kept.\n\n* `source_system_object_ids` (**int-list**, required): system object ids\n  of the objects to consolidate. All link references to them (in any link\n  field, including nested) are re-pointed to the target. A nested row\n  whose link would duplicate a sibling row already linking the target is\n  dropped — unless the row carries other data, then it is kept and\n  re-pointed. The target must not be part of the sources, duplicate ids\n  are rejected.\n* `target_system_object_id` (**int**, required, min. `1`): system object\n  id of the object the sources are consolidated into. It must have the\n  same objecttype as the sources; sources of another objecttype are\n  skipped with a warning. The target must not itself link any of the\n  sources (the consolidation would link it to itself): such a task is\n  rejected at save time with `ConsolidateTargetLinksSources`.\n* `dry_run` (**bool**, default `true`): only log what the task would do,\n  change nothing.\n* `delete_sources` (**bool**, default `true`): delete each source after\n  re-linking (delete policy `setnull`, the sources can be restored from\n  the trash).\n\n### `delete_objects`\n\nDeletes (or restores) the objects found by the task search.\n\n* `search` (**json**, required): a **fylr** search request which finds the\n  objects to process. Set `incremental` to `true` to only process objects\n  modified since the last task run.\n* `delete_policy` (**select**, default `setnull`): one of `setnull`\n  (unlink the deleted objects in other objects), `remove` (also delete\n  subordinate or reverse-linked objects), `purge` (purge objects from the\n  trash), `undelete` (restore objects from the trash).\n\n### `metadata`\n\nApplies mapped file metadata to the objects found by the task search.\n\n* `search` (**json**, required): a **fylr** search request which finds the\n  objects to process.\n* `create_object` (**json**): objecttype/mask configuration for objects\n  created from metadata.\n* `set_unset_tags` (**json**): tags to set or remove on the processed\n  objects, format: `{ \"tags\": [ { \"_id\": \u003ctag id\u003e, \"set\": \u003cbool\u003e } ] }`.\n* `overwrite_values` (**bool**): overwrite existing values with mapped\n  metadata.\n\n### `search`\n\nCounts the objects found by the task search.\n\n* `search` (**json**, required): a **fylr** search request.\n\n### `set_unset_tags`\n\nSets and removes tags on the objects found by the task search.\n\n* `search` (**json**, required): a **fylr** search request which finds the\n  objects to process. Set `incremental` to `true` to only process objects\n  modified since the last task run.\n* `set_unset_tags` (**json**, required): the tags to set or remove,\n  format: `{ \"tags\": [ { \"_id\": \u003ctag id\u003e, \"set\": \u003cbool\u003e } ] }`.\n\n### `sleep`\n\nDoes nothing but sleep, for development and testing (`debug` is set).\n\n* `runtime` (**int**): seconds to sleep.\n* `secret` (**secret**): unused, for testing.\n* `input` (**text**, default `default test string`): unused, for testing.\n",
      "get": {
        "responses": {
          "200": {
            "description": "Retrieve a list of available task modules.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "modules": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "Name of the module.\n"
                          },
                          "displayname": {
                            "type": "object",
                            "properties": {
                              "de-DE": {
                                "type": "string"
                              },
                              "en-US": {
                                "type": "string"
                              }
                            },
                            "example": {
                              "de-DE": "Deutscher text",
                              "en-US": "English text"
                            }
                          },
                          "description": {
                            "type": "object",
                            "properties": {
                              "de-DE": {
                                "type": "string"
                              },
                              "en-US": {
                                "type": "string"
                              }
                            },
                            "example": {
                              "de-DE": "Deutscher text",
                              "en-US": "English text"
                            }
                          },
                          "debug": {
                            "type": "boolean",
                            "description": "If set, this module is meant for developement, testing,\ndebug purposes only. Frontends are advised to not expose\nthis module publicly.\n"
                          },
                          "params": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "description": "Each item describes a config setting.",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "description": "The unique name of this config"
                                },
                                "group": {
                                  "type": "string",
                                  "description": "The **group** sets the tab this config variable is in."
                                },
                                "parameters": {
                                  "$ref": "#/components/schemas/ConfigParam"
                                },
                                "require_system_right": {
                                  "type": "string",
                                  "description": "System right which this config requires, e.g. \"system.root\" if it requires root rights."
                                },
                                "unauthenticated_visible": {
                                  "type": "boolean",
                                  "description": "If true, this config is visible to unauthenticated sessions (access token with no user)."
                                },
                                "unavailable": {
                                  "type": "boolean",
                                  "description": "If true, the feature this section configures is not available on\nthis instance (e.g. not included in the license). Frontends should\nrender the section greyed out but visible. Computed per request;\nomitted when false.\n"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No authenticated user. The request must carry a valid access token.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "The authenticated user lacks the `system.task` system right (and is\nnot `system.root`). Raised with code `SystemRightRequired`\n(`parameters.rights` lists the rights that would have satisfied the\ncheck).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemRightRequiredError"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/auth": {
      "x-path": "/oauth2",
      "servers": [
        {
          "url": "/api"
        }
      ],
      "description": "OAuth2 / OpenID Connect **authorization endpoint** (RFC 6749 §3.1).\nThis is where the browser web-app logs a user in. It authenticates\nthe end user — by password (`auth_method=easydb`, the default; also\n`ldap`, `email`, `collection`), anonymously (`anonymous`, when guest\nlogin is enabled), via SAML, or with an action code — and returns an\nauthorization response (an authorization `code`, `token` or\n`id_token`) by redirecting back to the client's `redirect_uri`.\n\nServed at `/api/oauth2/auth` — **not** under `/api/v1`. No prior\naccess token is required.\n",
      "get": {
        "summary": "Begin an authorization request (interactive login).",
        "description": "**Stay logged in:** opt-in per base config *Login* →\n`keep_login` (`off` by default, or a session lifetime of 7 or 30\ndays). When enabled, the login form offers a \"Stay logged in\"\ncheckbox (`keep_login=1`); a successful login — including a passed\ntwo-factor challenge — then additionally sets the persistent,\nHttpOnly `fylr-keep-login` browser cookie. A later request to this\nendpoint without credentials silently re-authorizes the cookie's\nuser (no login form, a fresh authorization response;\n`authenticated.method` of such a session reports `keep_login`). The\nlifetime slides on each use; `/logout` revokes the server-side\nsession and expires the cookie. When the option is `off`,\n`keep_login=1` is ignored and existing cookies are dropped.\n\n**Session binding (anti-hijacking):** an access/refresh token issued\nto the browser here is bound to the browser's long-lived, HttpOnly\n`fylr-browser-id` cookie, and the keep-login cookie above is bound\nthe same way. That cookie must then accompany the\n`Authorization: Bearer` token on every API request; a token — or a\nkeep-login cookie — presented from a different browser, i.e. without\nthe matching cookie, is rejected as invalid (`InvalidToken`), so a\nstolen bearer token on its own cannot be replayed. Binding is silent\nand always on. A login whose token is consumed on a **different\norigin** than this **fylr** — a third-party OAuth client (a\ncross-origin `redirect_uri`) or a cross-server *webOnly* frontend (a\ncross-origin `state` redirect) — is issued **unbound** instead,\nsince that origin's requests would not carry the cookie.\n",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "client_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The OAuth2 client identifier."
          },
          {
            "name": "response_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "code",
                "token",
                "id_token"
              ]
            },
            "description": "The OAuth2/OIDC response type. Combined types such as\n`code id_token` are also supported.\n"
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "Where to redirect with the result. Must match the client\nregistration.\n"
          },
          {
            "name": "scope",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Space-separated scopes, within the client's allowed set (a\nclient that configures none may use all of `read`, `write`,\n`openid`, `offline`). Their effect in fylr:\n\n  * `openid` — also issue an OpenID Connect `id_token` (an\n    RS256 JWT) alongside the access token. (The\n    `/api/oauth2/userinfo` endpoint itself accepts any valid\n    access token and is not gated on this scope.)\n  * `offline` — request a refresh token. A refresh token is\n    issued (for the authorization-code and password grants)\n    only when this scope is granted, and granting it also\n    applies the configured refresh-token expiration override.\n    fylr accepts both `offline` and the OIDC-standard\n    `offline_access` for this.\n  * `read`, `write` — capability labels only; they are **not**\n    consulted to authorize API calls. Actual API authorization\n    uses fylr's per-user/per-pool ACL rights, which are\n    independent of these OAuth2 scopes despite the matching\n    names.\n"
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque value echoed back to the client."
          },
          {
            "name": "code_challenge",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "PKCE code challenge."
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "S256"
              ]
            }
          },
          {
            "name": "auth_method",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "easydb",
                "ldap",
                "email",
                "collection",
                "saml",
                "action_code",
                "anonymous",
                "auto"
              ],
              "default": "easydb"
            },
            "description": "fylr login method (default `easydb`). The endpoint accepts a\ncomma-separated list and tries the methods in order; the\nweb-app sends a single value. Each method authenticates a\nspecific user type:\n\n  * `easydb` — `login` + `password` against the fylr user\n    database (user types `easydb`, `system`,\n    `easydb_self_register`). Also the fallback when\n    `auth_method` is set to an unrecognised value. (An empty\n    `auth_method` parses to `auto`, not `easydb`.)\n  * `ldap` — `login` + `password` bound against a configured\n    LDAP directory; provisions/updates an `ldap` user. Only\n    available when an LDAP connection is configured and the\n    license permits external auth.\n  * `email` — passwordless login for invited `email` users:\n    `login` plus the account UUID (sent in the `password`\n    field) — the UUID is the secret.\n  * `collection` — `login` + `password` for `collection` user\n    accounts.\n  * `saml` — SAML 2.0 SSO; no credentials in the form. The\n    first call redirects to the IdP, then the returned\n    assertion provisions/updates an `sso` user. Only available\n    when SAML is configured and the license permits external\n    auth.\n  * `action_code` — a one-time `secret` + `action_code` pair\n    used by internal redirect flows (forced password change,\n    system messages); logs in whichever user the code was\n    issued for. Single-use.\n  * `anonymous` — guest login, no credentials; binds to a\n    per-browser anonymous user. Only when guest login is\n    enabled (base config `guest`).\n  * `auto` — server-side selector (the web-app default):\n    resolves to `anonymous` when guests are allowed and no\n    `login` is supplied, otherwise to password login\n    (`easydb`, then `ldap` when configured).\n"
          },
          {
            "name": "login",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "User login (for password methods)."
          },
          {
            "name": "password",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "User password (for password methods)."
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to the client `redirect_uri` carrying the\nauthorization `code`, `token` or `id_token` (per\n`response_type`). May instead redirect (`303`) to an\ninterstitial page: two-factor authentication for enforced\nusers — `/api/page/twoFactor` (enter the email / authenticator\ncode), `/api/page/twoFactorChoose` (method picker),\n`/api/page/twoFactorSetup` or `/api/page/twoFactorSetupPasskey`\n(first-time enrollment) — or `/api/page/setPassword` (forced\npassword change) or `/api/page/showMessage` (pending tasks).\nAfter a passed challenge the page redirects back here with\n`auth_method=action_code` to complete the original request\nwithout re-entering the password.\n"
          },
          "200": {
            "description": "The HTML login form, rendered when credentials are absent or\ninvalid (with a generic `server.oauth2.LoginFailed` message).\n",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Submit the login form / authorization request.",
        "description": "Same as `GET`, but the parameters are sent as an\n`application/x-www-form-urlencoded` body — used when the login\nform is submitted. The keep-login and session-binding notes on\n`GET` apply here as well.\n",
        "security": [
          {}
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string"
                  },
                  "response_type": {
                    "type": "string"
                  },
                  "redirect_uri": {
                    "type": "string",
                    "format": "uri"
                  },
                  "scope": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string"
                  },
                  "auth_method": {
                    "type": "string",
                    "enum": [
                      "easydb",
                      "ldap",
                      "email",
                      "collection",
                      "saml",
                      "action_code",
                      "anonymous",
                      "auto"
                    ]
                  },
                  "login": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  },
                  "keep_login": {
                    "type": "string",
                    "enum": [
                      "1"
                    ],
                    "description": "The \"Stay logged in\" checkbox. `1` mints the persistent\n`fylr-keep-login` cookie after a fully completed login\n(see the endpoint description). Ignored unless the base\nconfig enables the feature (*Login* → `keep_login`).\n"
                  },
                  "secret": {
                    "type": "string",
                    "description": "Action-code secret (for `auth_method=action_code`)."
                  },
                  "action_code": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "302": {
            "description": "Redirect to `redirect_uri` with the authorization result."
          },
          "200": {
            "description": "HTML login form (on missing/invalid credentials).",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/token": {
      "x-path": "/oauth2",
      "servers": [
        {
          "url": "/api"
        }
      ],
      "description": "OAuth2 **token endpoint** (RFC 6749 §3.2). Exchanges an\nauthorization code, resource-owner password credentials, client\ncredentials, or a refresh token for an access token (and, for the\n`openid` scope, an `id_token`). Access tokens are bearer tokens; the\nlifetime is 24 hours by default and can be overridden by the base\nconfig (`oauth2` access-token expiration).\n\nServed at `/api/oauth2/token` — **not** under `/api/v1`.\n",
      "post": {
        "summary": "Issue an access token.",
        "description": "`application/x-www-form-urlencoded` request. Confidential clients\nauthenticate with `client_id`/`client_secret` (form fields or HTTP\nBasic); public clients send only `client_id`. For the resource-owner\npassword grant fylr validates `username`/`password` against the\neasydb, collection, email, then LDAP login methods in turn.\n\n**Two-factor authentication:** the password grant cannot present a\nsecond factor, so for users who are required to use 2FA it is\nrefused with `invalid_grant` (indistinguishable from a wrong\npassword) — unless the base config deliberately allows it\n(*Two-factor authentication* → *Allow password grant*).\n`system:root` is always exempt.\n\n**Session binding:** a token minted here is bound to the\n`fylr-browser-id` cookie when the request carries one (see the\n*Session binding* note on the authorization endpoint's `GET`); the\npassword and client-credentials grants normally send no cookie and\nso receive **unbound** tokens that work without it.\n",
        "security": [
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "grant_type"
                ],
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "authorization_code",
                      "password",
                      "client_credentials",
                      "refresh_token",
                      "implicit"
                    ]
                  },
                  "code": {
                    "type": "string",
                    "description": "Authorization code (`grant_type=authorization_code`)."
                  },
                  "redirect_uri": {
                    "type": "string",
                    "format": "uri"
                  },
                  "refresh_token": {
                    "type": "string",
                    "description": "Refresh token (`grant_type=refresh_token`)."
                  },
                  "username": {
                    "type": "string",
                    "description": "Resource-owner login (`grant_type=password`)."
                  },
                  "password": {
                    "type": "string",
                    "description": "Resource-owner password (`grant_type=password`)."
                  },
                  "scope": {
                    "type": "string",
                    "description": "Space-separated scopes."
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "code_verifier": {
                    "type": "string",
                    "description": "PKCE code verifier."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The issued token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": {
                      "type": "string"
                    },
                    "token_type": {
                      "type": "string",
                      "enum": [
                        "bearer"
                      ]
                    },
                    "expires_in": {
                      "type": "integer",
                      "description": "Seconds until the access token expires (86400 by\ndefault; configurable in the base config).\n"
                    },
                    "refresh_token": {
                      "type": "string"
                    },
                    "scope": {
                      "type": "string"
                    },
                    "id_token": {
                      "type": "string",
                      "description": "JWT id_token (RS256), present for the `openid` scope."
                    }
                  }
                },
                "example": {
                  "access_token": "8a1b2c3d…",
                  "token_type": "bearer",
                  "expires_in": 86400,
                  "scope": "read write openid offline"
                }
              }
            }
          },
          "400": {
            "description": "RFC 6749 error response (`invalid_request`, `invalid_grant`,\n`unsupported_grant_type`, `invalid_client`, ...). fylr's\ninternal error is appended to `error_description`.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "error_description": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/revoke": {
      "x-path": "/oauth2",
      "servers": [
        {
          "url": "/api"
        }
      ],
      "description": "OAuth2 **token revocation** endpoint (RFC 7009). Revokes an access\nor refresh token; the web-app uses it to log out, and a\n`USER_LOGOUT` audit event is written for the token's user. Per\nRFC 7009 it returns `200` even for an unknown token.\n\nServed at `/api/oauth2/revoke` — **not** under `/api/v1`.\n",
      "post": {
        "summary": "Revoke a token (logout).",
        "security": [
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "The access or refresh token to revoke."
                  },
                  "token_type_hint": {
                    "type": "string",
                    "enum": [
                      "access_token",
                      "refresh_token"
                    ]
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The token was revoked (also returned for an unknown token)."
          }
        }
      }
    },
    "/oauth2/introspect": {
      "x-path": "/oauth2",
      "servers": [
        {
          "url": "/api"
        }
      ],
      "description": "OAuth2 **token introspection** endpoint (RFC 7662). Returns the\nactive state and metadata of a token. The caller must be an\nauthorized client.\n\nServed at `/api/oauth2/introspect` — **not** under `/api/v1`.\n",
      "post": {
        "summary": "Introspect a token.",
        "security": [
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "token_type_hint": {
                    "type": "string",
                    "enum": [
                      "access_token",
                      "refresh_token"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Introspection result. `active` is `false` for an unknown,\nexpired or revoked token; the other fields are present only\nwhen the token is active.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "active": {
                      "type": "boolean"
                    },
                    "scope": {
                      "type": "string"
                    },
                    "client_id": {
                      "type": "string"
                    },
                    "sub": {
                      "type": "string"
                    },
                    "exp": {
                      "type": "integer"
                    },
                    "iat": {
                      "type": "integer"
                    },
                    "token_type": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "active": true,
                  "scope": "read write",
                  "sub": "root"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/userinfo": {
      "x-path": "/oauth2",
      "servers": [
        {
          "url": "/api"
        }
      ],
      "description": "OpenID Connect **UserInfo** endpoint. Returns claims about the user\nidentified by the presented bearer access token, filtered by the\ninstance's `userinfo` allowlist. `sub` is always returned; every\nother claim appears only when its name is in the allowlist.\n\nThe allowlist is configured in the base config under\n`openid.userinfo` — a list of claim names (for example `email`,\n`displayname`, `first_name`), bound to the internal `OpenIdUserInfo`\nsetting. The same list drives `claims_supported` in the discovery\ndocument.\n\nServed at `/api/oauth2/userinfo` — **not** under `/api/v1`. Like all\n`/api/oauth2` and `/api/v1` routes, the request runs through the\n`setSessionFromToken` middleware, which accepts the access token via\nthe `Authorization: Bearer` header, the `X-Fylr-Authorization` header\n(a Safari workaround) or the `access_token` query parameter.\n`userinfo` is the only OAuth2 endpoint that consumes the resulting\nsession user; the other endpoints parse the token themselves from the\nform body for their RFC operations.\n",
      "get": {
        "summary": "Get claims for the access-token user.",
        "responses": {
          "200": {
            "description": "The user's OpenID claims.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserInfo"
                }
              }
            }
          },
          "400": {
            "description": "No valid user could be resolved from the token. Code\n`InvalidToken` (`realm: api`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Get claims for the access-token user (form POST).",
        "responses": {
          "200": {
            "description": "The user's OpenID claims.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserInfo"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/openid-configuration": {
      "x-path": "/.well-known",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "OpenID Connect **discovery document** (provider metadata). A public,\nunauthenticated document advertising fylr's OAuth2 / OpenID Connect\nissuer and endpoints so that OIDC clients can configure themselves.\n\nServed at the server root (`/.well-known/openid-configuration`) —\n**not** under `/api/v1`. The endpoint URLs it returns are absolute,\nbuilt from the instance's configured external URL\n(`fylr.externalURL`), and point at `/api/oauth2/*`.\n\nThe route is not method-restricted: any HTTP method returns the same\nmetadata document with status `200`.\n",
      "get": {
        "summary": "Fetch the OpenID Connect provider metadata.",
        "security": [
          {}
        ],
        "responses": {
          "200": {
            "description": "The discovery document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "issuer",
                    "authorization_endpoint",
                    "token_endpoint",
                    "introspection_endpoint",
                    "revocation_endpoint",
                    "userinfo_endpoint"
                  ],
                  "properties": {
                    "issuer": {
                      "type": "string",
                      "format": "uri",
                      "description": "The instance's external URL."
                    },
                    "authorization_endpoint": {
                      "type": "string",
                      "format": "uri"
                    },
                    "token_endpoint": {
                      "type": "string",
                      "format": "uri"
                    },
                    "introspection_endpoint": {
                      "type": "string",
                      "format": "uri"
                    },
                    "revocation_endpoint": {
                      "type": "string",
                      "format": "uri"
                    },
                    "userinfo_endpoint": {
                      "type": "string",
                      "format": "uri"
                    },
                    "response_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "grant_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "scopes_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "claims_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The claim names `userinfo` may return — always `sub`,\nplus every claim enabled in the base config's\n`openid.userinfo` list (`email_verified` is included\nonly when `email` is enabled).\n"
                    },
                    "code_challenge_methods_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Always `[\"S256\"]`."
                    },
                    "id_token_signing_alg_values_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Always `[\"RS256\"]`."
                    },
                    "subject_types_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Always `[\"public\"]`."
                    }
                  }
                },
                "example": {
                  "issuer": "https://demo.fylr.dev",
                  "authorization_endpoint": "https://demo.fylr.dev/api/oauth2/auth",
                  "token_endpoint": "https://demo.fylr.dev/api/oauth2/token",
                  "introspection_endpoint": "https://demo.fylr.dev/api/oauth2/introspect",
                  "revocation_endpoint": "https://demo.fylr.dev/api/oauth2/revoke",
                  "userinfo_endpoint": "https://demo.fylr.dev/api/oauth2/userinfo",
                  "response_types_supported": [
                    "id_token",
                    "code",
                    "token",
                    "id_token token",
                    "code id_token",
                    "code token",
                    "code id_token token"
                  ],
                  "grant_types_supported": [
                    "implicit",
                    "refresh_token",
                    "authorization_code",
                    "password",
                    "client_credentials"
                  ],
                  "scopes_supported": [
                    "read",
                    "write",
                    "openid",
                    "offline"
                  ],
                  "claims_supported": [
                    "sub",
                    "email",
                    "email_verified"
                  ],
                  "code_challenge_methods_supported": [
                    "S256"
                  ],
                  "id_token_signing_alg_values_supported": [
                    "RS256"
                  ],
                  "subject_types_supported": [
                    "public"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/inspect/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Instance overview** — the /inspect home dashboard. Summarises the running\ninstance: database, indexer, settings, index names, connected storage\nbackends and license.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Instance overview (home dashboard).",
        "description": "Returns the instance overview. The whitelisted JSON exposes the compiled\nbase configuration and the list of connected storage backends.\n",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted instance overview.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "BaseConfig": {
                      "type": "object",
                      "description": "The compiled base configuration of the instance (sensitive\nvalues removed).\n"
                    },
                    "Backends": {
                      "type": "array",
                      "description": "The connected storage backends (file / S3 / Azure).",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/config/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Base config dump** — the compiled base configuration and the list of\nconfig layers that produced it.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Compiled base configuration.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted config dump.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Config": {
                      "type": "object",
                      "description": "The effective, merged base configuration."
                    },
                    "BaseConfigList": {
                      "type": "array",
                      "description": "The individual config layers that were merged.",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/plugins/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Plugin dump** — the installed plugins and their manifests.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Installed plugins.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted plugin dump.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Plugins": {
                      "type": "array",
                      "description": "The installed plugins and their manifest metadata.",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/tags/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Tag dump** — the configured tags and tag groups.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Tags and tag groups.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted tag dump.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Tags": {
                      "type": "array",
                      "description": "The configured tags and tag groups.",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/users/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**User dump** — the users known to the ACL, used by the inspect user\nselector.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Users (ACL).",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted user list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Users": {
                      "type": "array",
                      "description": "The users known to the ACL.",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/objecttypes/{objecttype}/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Objecttype stats** — per-objecttype statistics for a single objecttype.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Statistics for one objecttype.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "objecttype",
            "in": "path",
            "required": true,
            "description": "Objecttype name or id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` for the whitelisted JSON projection.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted objecttype stats.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "OtStats": {
                      "type": "object",
                      "description": "Per-objecttype statistics (object counts, index state and\nrelated figures).\n"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/pools/{pool}/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Pool stats** — statistics for a single pool and its sub-pools.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Statistics for one pool.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "pool",
            "in": "path",
            "required": true,
            "description": "Pool id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted pool stats.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "PoolStats": {
                      "type": "object",
                      "description": "Statistics for the pool."
                    },
                    "PoolStatsSubpools": {
                      "type": "array",
                      "description": "Statistics for each sub-pool.",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/objects/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Object list dump** — a paged list of the system object ids of an\nobjecttype, used to monitor \"not found on READ\" per objecttype.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Paged object id list for an objecttype.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "objecttype",
            "in": "query",
            "required": false,
            "description": "Objecttype to list.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted object-list dump.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "SystemObjectIds": {
                      "type": "array",
                      "description": "The system object ids on this page.",
                      "items": {
                        "type": "integer"
                      }
                    },
                    "Objecttype": {
                      "type": "string"
                    },
                    "Filter": {
                      "type": "object"
                    },
                    "Versions": {
                      "type": "object"
                    },
                    "Index": {
                      "type": "string"
                    },
                    "Order": {
                      "type": "string"
                    },
                    "Offset": {
                      "type": "integer"
                    },
                    "Limit": {
                      "type": "integer"
                    },
                    "Prev": {
                      "type": "integer",
                      "description": "Offset of the previous page, if any."
                    },
                    "Next": {
                      "type": "integer",
                      "description": "Offset of the next page, if any."
                    },
                    "ParseErr": {
                      "type": "string",
                      "description": "Set when the request parameters could not be parsed."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/objects/list/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Index read map** — objects indexed by read table name, used by external\nmonitoring to track \"not found READ\" per objecttype.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Objects indexed by read table.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted index read map.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "IndexedByTableNameRead": {
                      "type": "object",
                      "description": "Map of read table name to the objects indexed under it.\n"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/objects/{systemObjectId}/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Single object dump** — renders one object by system object id against any\ndatamodel version, for debugging rendering and re-index behaviour.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Render one object against a datamodel version.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "systemObjectId",
            "in": "path",
            "required": true,
            "description": "System object id.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted single-object dump.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ReindexSystemObjectIds": {
                      "type": "array",
                      "description": "System object ids scheduled for re-index by this render.",
                      "items": {
                        "type": "integer"
                      }
                    },
                    "DatamodelSelect": {
                      "type": "array",
                      "description": "The datamodel versions selectable for rendering.",
                      "items": {
                        "type": "object"
                      }
                    },
                    "CurrentDatamodelId": {
                      "type": "integer",
                      "description": "The current (live) datamodel id."
                    },
                    "RenderingDatamodelId": {
                      "type": "integer",
                      "description": "The datamodel id used to render this response."
                    },
                    "ObjectDatamodelId": {
                      "type": "integer",
                      "description": "The datamodel id the object was last written with."
                    },
                    "LatestLinked": {
                      "type": "object",
                      "description": "The latest linked-object state."
                    },
                    "Warning": {
                      "type": "string",
                      "description": "A rendering warning, if any."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/collections/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Collection tree dump** — a paged, searchable view of the whole collection\ntree across all users. Used by the test suite to check paging, search and\ntree building.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Paged, searchable collection tree.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Filter collections by name or reference.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "owner",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted collection-tree dump.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ColInfos": {
                      "type": "array",
                      "description": "The collections on this page, with parent/child links.",
                      "items": {
                        "type": "object"
                      }
                    },
                    "Filter": {
                      "type": "object"
                    },
                    "Markers": {
                      "type": "object"
                    },
                    "UserType": {
                      "type": "string"
                    },
                    "Order": {
                      "type": "string"
                    },
                    "Offset": {
                      "type": "integer"
                    },
                    "Limit": {
                      "type": "integer"
                    },
                    "TotalCount": {
                      "type": "integer"
                    },
                    "LoadParents": {
                      "type": "boolean"
                    },
                    "LoadChildren": {
                      "type": "boolean"
                    },
                    "Prev": {
                      "type": "integer"
                    },
                    "Next": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/customdata/{id}/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Custom-data event dump** — the custom-data-type event for one entry.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Custom-data-type event.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted custom-data event.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Event": {
                      "type": "object",
                      "description": "The custom-data-type event."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/system/status/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Server stats** — object, index and queue statistics for the instance.\nThis is the /inspect projection of the same figures the `/api/v1/system/status`\nendpoint returns.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Server statistics.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted server statistics.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Stats": {
                      "type": "object",
                      "description": "Object counts per objecttype and basetype, index- and\nfile-queue depth and per-index storage sizes.\n"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/system/janitor/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Janitor dump** — the background janitor's events and the query behind the\ncurrent view.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Janitor events.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted janitor dump.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Event": {
                      "type": "object",
                      "description": "The selected janitor event."
                    },
                    "Query": {
                      "type": "object",
                      "description": "The query behind the current janitor view."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/sqlquery/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**SQL query console** — runs an arbitrary read-only SQL statement and returns\nthe result. Only available when `fylr.debug.inspectEnableSqlQuery` is set;\nit is a powerful, destructive-capable tool and is the main reason the backend\nport must stay private.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Run an SQL query (debug builds only).",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "The SQL statement to run.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted query result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "SqlQuery": {
                      "type": "object",
                      "description": "The query, its columns and the result rows."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/recalcterms/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Term recalculation** — status of the suggestion-term rebuild. Poll this to\nwatch a recalculation run to completion; the rebuild itself is triggered with\n`POST /inspect/recalcterms`.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "Term-recalculation status.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted recalculation status.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "RecalcTerms": {
                      "type": "object",
                      "description": "The current state of the term recalculation (running / idle,\nprogress and per-objecttype detail).\n"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/migration/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Migration / backup list** — the available backups. The test suite polls\nthis to drive and watch `POST /inspect/migration` backup / restore actions.\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "List backups.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "description": "Send `application/json` to receive the whitelisted JSON projection\ninstead of the HTML dashboard. Equivalent to the `?accept=application/json`\nquery parameter.\n",
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted backup list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Backups": {
                      "type": "array",
                      "description": "The available backups.",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/inspect/migration/{backup}/": {
      "x-path": "/inspect",
      "servers": [
        {
          "url": "/"
        }
      ],
      "description": "**Backup detail** — one backup and, with `--include-files`, a directory\nlisting of its contents (top level or a sub-path).\n\n\u003e **Access.** `/inspect` is fylr's root-only operations console. On the\n\u003e public **webapp port** it is reverse-proxied behind a session check and\n\u003e requires the **`system.root`** right; on the **backend port** it is mounted\n\u003e with no authentication and must therefore stay on a private network. It is\n\u003e **not** part of the token-authenticated `/api/v1` surface, so the security\n\u003e schemes of this document do not apply.\n",
      "get": {
        "summary": "One backup and its file listing.",
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "backup",
            "in": "path",
            "required": true,
            "description": "Backup name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "application/json"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whitelisted backup detail.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "Backup": {
                      "type": "object",
                      "description": "The backup's metadata."
                    },
                    "Files": {
                      "type": "array",
                      "description": "Directory listing of the backup at SubPath.",
                      "items": {
                        "type": "object"
                      }
                    },
                    "SubPath": {
                      "type": "string",
                      "description": "The sub-path within the backup being listed."
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Access token in the `Authorization` header:\n`Authorization: Bearer \u003ctoken\u003e`.\n"
      },
      "AccessTokenQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "access_token",
        "description": "Access token as the `access_token` query parameter — handy for\nlinks and downloads; prefer the `Authorization` header otherwise.\n"
      },
      "FylrAuthHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Fylr-Authorization",
        "description": "`Bearer \u003ctoken\u003e` in the `X-Fylr-Authorization` header — a\nfallback for Safari, which overwrites `Authorization`.\n"
      }
    },
    "schemas": {
      "LocaValue": {
        "type": "object",
        "properties": {
          "de-DE": {
            "type": "string"
          },
          "en-US": {
            "type": "string"
          }
        },
        "example": {
          "de-DE": "Deutscher text",
          "en-US": "English text"
        }
      },
      "UserInfo": {
        "type": "object",
        "description": "OpenID Connect claims for the authenticated user, returned by\n`GET`/`POST` `/api/oauth2/userinfo`. `sub` is always present; every\nother claim is returned only when its name is listed in the instance's\n`userinfo` allowlist (base-config `OpenIdUserInfo`).\n",
        "required": [
          "sub"
        ],
        "properties": {
          "sub": {
            "type": "string",
            "description": "Subject identifier — the user's login, or email, or the numeric\nuser id if neither is set. Always present, not gated by the\nallowlist.\n"
          },
          "displayname": {
            "type": "string",
            "description": "The user's compiled display name."
          },
          "email": {
            "type": "string",
            "description": "Email address. An empty string when the user has none (but the\n`email` claim is enabled).\n"
          },
          "email_verified": {
            "type": "boolean",
            "description": "Whether the email address has been confirmed. Returned alongside\n`email`.\n"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "company": {
            "type": "string"
          },
          "department": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "address_supplement": {
            "type": "string"
          },
          "street": {
            "type": "string"
          },
          "house_number": {
            "type": "string"
          },
          "postal_code": {
            "type": "string"
          },
          "town": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "country": {
            "type": "string"
          }
        },
        "example": {
          "sub": "root",
          "displayname": "Root User",
          "email": "root@example.org",
          "email_verified": true
        }
      },
      "ExportVersion": {
        "type": "object",
        "description": "One rendition-selection entry. Used both as an element of\n`export.classes.\u003cclass\u003e[]` and of `export.assets.\u003cfile-id\u003e.versions`.\nEach entry produces one file in the export for every matching source\nfile. Validated by `exportVersions.ApiToObject`\n(internal/api/export/export_api.go:153-207).\n",
        "additionalProperties": false,
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "original",
              "current",
              "version",
              "custom"
            ],
            "description": "Which rendition of the file to export.\n`original` — the root/original file (resolves to the original\neven when the current value is a produced version).\n`current` — the file value as currently set.\n`version` — a named produced version; requires `version`.\n`custom` — an on-the-fly rendition described by `custom` or, by\nname, by `custom_version_preset` (image class only).\n"
          },
          "metadata": {
            "description": "Metadata-embedding rule for the exported file. One of the\nstrings `standard` (apply the object's standard image-export\nmetadata mapping), `keep` (leave embedded metadata untouched),\n`remove` (strip IPTC / XMP / Photoshop tags via exiftool), or an\ninteger mapping-profile id (a custom metadata mapping).\n`null` / omitted is treated as `standard`. Any other value is\nrejected.\n",
            "default": "standard",
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "standard",
                  "keep",
                  "remove"
                ]
              },
              {
                "type": "integer",
                "description": "A metadata-mapping profile id."
              }
            ]
          },
          "version": {
            "type": "string",
            "description": "Name of the produced version to export. Required when\n`type` = `version`; matched against the file's available child\nversions by name. Ignored for other `type` values.\n"
          },
          "custom": {
            "$ref": "#/components/schemas/ExportCustomVersion"
          },
          "custom_version_preset": {
            "type": "string",
            "description": "Name of a custom version preset configured in the base config\nblock `custom_version_presets`. An alternative to an inline\n`custom` object when `type` = `custom`: the server resolves the\npreset to its options. Set either `custom` or\n`custom_version_preset`, not both; an unknown name is rejected.\nThe produced file is named after the preset instead of `custom`.\n"
          }
        }
      },
      "ExportCustomVersion": {
        "type": "object",
        "description": "Parameters for an on-the-fly custom rendition (only meaningful when\nthe enclosing version's `type` = `custom`, and only for files of\nclass `image`). Drives the internal `_produce:produce` recipe at\ndelivery time.\n",
        "additionalProperties": false,
        "properties": {
          "watermark": {
            "type": "boolean",
            "default": false,
            "description": "Whether to apply a watermark to the rendition."
          },
          "quality": {
            "description": "Output quality. Either a keyword or a numeric string `1`-`100`.\nKeywords map to: `low`/`small` = 50, `medium` = 75, `high` = 85,\n`maximum` = 100. A numeric value must be an integer in the range\n1..100 (`\u003e0` and `\u003c=100`); `0`, negative, `\u003e100` or non-numeric\nvalues are rejected. An empty string is allowed and skipped.\nValidated via `baseconfig.QualityAsInt`.\n",
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "low",
                  "small",
                  "medium",
                  "high",
                  "maximum"
                ]
              },
              {
                "type": "string",
                "pattern": "^([1-9]|[1-9][0-9]|100)$",
                "description": "Numeric quality 1..100 as a string."
              }
            ]
          },
          "format": {
            "type": "string",
            "description": "Output image format / file extension. `keep` or empty keeps the\nsource extension; any other value becomes the produced file's\nextension and target format. NOT validated server-side — passed\nthrough to the produce recipe. Common values listed in `enum`.\n",
            "enum": [
              "keep",
              "jpeg",
              "tiff",
              "png",
              "bmp"
            ]
          },
          "colorspace": {
            "type": "string",
            "description": "Target colorspace passed to the produce recipe (ImageMagick\ncolorspace name, e.g. `sRGB`, `RGB`, `Gray`, `CMYK`). `keep`\n(or empty) leaves the colorspace unchanged. NOT enum-validated\nserver-side.\n"
          },
          "colorprofile": {
            "type": "string",
            "description": "Name of an ICC color profile to assign. Validated at save time\nagainst the available color profiles (the built-in `.icc`\nprofiles shipped with fylr plus any customer-configured /\nuploaded profiles); an unknown name is rejected. `\"\"` or `\"-\"`\nmeans no profile. Because customer profiles are dynamic this is\nnot a fixed enum; the built-in profiles are listed below.\n",
            "enum": [
              "",
              "-",
              "ACESCG Linear",
              "AdobeRGB1998",
              "DCI(P3) RGB",
              "Display P3",
              "eciRGB_v2",
              "Generic CMYK Profile",
              "Generic Gray Gamma 2.2 Profile",
              "Generic Gray Profile",
              "Generic Lab Profile",
              "Generic RGB Profile",
              "Generic XYZ Profile",
              "ISOcoated_v2_eci",
              "ITU-2020",
              "ITU-709",
              "ROMM RGB",
              "sRGB Profile",
              "sRGB_IEC61966-2-1_black_scaled"
            ]
          },
          "size": {
            "type": "string",
            "enum": [
              "keep",
              "custom"
            ],
            "description": "Resize strategy. Only `custom` activates custom resizing (then\n`custom_size` and the `custom_*_pixel` fields apply). `keep`\nleaves the size unchanged.\n"
          },
          "custom_size": {
            "type": "string",
            "enum": [
              "dimension_max",
              "dimension_min",
              "width",
              "height",
              "cover",
              "contain"
            ],
            "description": "Custom-size mode (applies when `size` = `custom`). Validated\nagainst the known dimensions; an unsupported value is rejected.\n`dimension_max` / `dimension_min` / `width` / `height` use\n`custom_size_pixel` as the single bound (longest side, shortest\nside, width, or height). `cover` / `contain` use\n`custom_width_pixel` + `custom_height_pixel` as a target box.\n"
          },
          "dpi": {
            "type": "integer",
            "default": 0,
            "description": "Output DPI passed to the produce recipe."
          },
          "custom_size_pixel": {
            "type": "integer",
            "default": 0,
            "description": "Single pixel bound used when `custom_size` is `dimension_max`,\n`dimension_min`, `width`, or `height`.\n"
          },
          "custom_width_pixel": {
            "type": "integer",
            "default": 0,
            "description": "Target width in pixels used when `custom_size` is `cover` or\n`contain`. Swapped with `custom_height_pixel` when\n`transform.rotate-z` is 90 or 270.\n"
          },
          "custom_height_pixel": {
            "type": "integer",
            "default": 0,
            "description": "Target height in pixels used when `custom_size` is `cover` or\n`contain`. Swapped with `custom_width_pixel` when\n`transform.rotate-z` is 90 or 270.\n"
          },
          "transform": {
            "$ref": "#/components/schemas/ExportTransform"
          }
        }
      },
      "ExportTransform": {
        "type": "object",
        "description": "Geometric transform applied to a custom rendition. Passed to the\nproduce recipe.\n",
        "additionalProperties": false,
        "properties": {
          "rotate-x": {
            "type": "integer",
            "default": 0,
            "description": "A non-zero value mirrors the image on the x axis. Mutually\nexclusive with a non-zero `rotate-y`.\n"
          },
          "rotate-y": {
            "type": "integer",
            "default": 0,
            "description": "A non-zero value mirrors the image on the y axis. Mutually\nexclusive with a non-zero `rotate-x`.\n"
          },
          "rotate-z": {
            "type": "integer",
            "default": 0,
            "description": "In-plane rotation in degrees. Values 90 and 270 swap width and\nheight for `cover` / `contain` custom sizes.\n"
          },
          "crop": {
            "description": "Optional crop rectangle; `null` means no crop.",
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "top": {
                    "type": "integer",
                    "default": 0,
                    "description": "Crop offset from the top, in pixels."
                  },
                  "left": {
                    "type": "integer",
                    "default": 0,
                    "description": "Crop offset from the left, in pixels."
                  },
                  "width": {
                    "type": "integer",
                    "default": 0,
                    "description": "Crop width, in pixels."
                  },
                  "height": {
                    "type": "integer",
                    "default": 0,
                    "description": "Crop height, in pixels."
                  }
                }
              }
            ]
          }
        }
      },
      "ExportEasField": {
        "type": "object",
        "description": "Per-asset-field export options. Keyed under `export.eas_fields` by a\ndatamodel field api-name (`objecttype.field`). The key must resolve\nto a field whose column type is `files` (an asset field) and whose\nrequired merge depth is `\u003c= merge_max_depth`.\n",
        "additionalProperties": false,
        "properties": {
          "files": {
            "type": "boolean",
            "default": false,
            "description": "Whether to ship the actual binary files for this asset field.\nIf false, only `data` descriptors (if any) are processed.\n"
          },
          "include_non_preferred": {
            "type": "boolean",
            "default": false,
            "description": "If true, non-preferred files in a multi-file asset value are\nalso exported; if false, only the preferred file is exported\n(unless overridden per file via `export.assets`).\n"
          },
          "data": {
            "type": "array",
            "description": "Extra metadata-data descriptors emitted alongside (or instead\nof) the binary files.\n",
            "items": {
              "$ref": "#/components/schemas/ExportFieldData"
            }
          }
        }
      },
      "ExportFieldData": {
        "type": "object",
        "description": "One metadata-data descriptor for an asset field. References a\nspecific rendition and a verbosity.\n",
        "additionalProperties": false,
        "required": [
          "type",
          "format"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "original",
              "current",
              "version"
            ],
            "description": "Which rendition the metadata describes."
          },
          "format": {
            "type": "string",
            "enum": [
              "long",
              "short"
            ],
            "description": "Verbosity of the embedded file metadata. `long` = full,\n`short` = reduced.\n"
          },
          "version": {
            "type": "string",
            "description": "Produced-version reference in the form `\u003cclass\u003e.\u003cversion-name\u003e`\n(e.g. `video.preview`). Only relevant when `type` = `version`;\nthe `\u003cclass\u003e` part must equal the file's class.\n"
          }
        }
      },
      "ExportAsset": {
        "type": "object",
        "description": "Object form of an `export.assets.\u003cfile-id\u003e` value, selecting an\nexplicit version list for one file. (The other accepted forms are\nboolean `true` = use the class defaults, and `false` = skip the\nfile.)\n",
        "additionalProperties": false,
        "properties": {
          "versions": {
            "type": "array",
            "description": "Explicit list of rendition selections for this file, used\ninstead of the class defaults.\n",
            "items": {
              "$ref": "#/components/schemas/ExportVersion"
            }
          },
          "eas_parent_id": {
            "type": "integer",
            "format": "int64",
            "default": 0,
            "description": "Optional parent asset/file id this file belongs to."
          },
          "json": {
            "type": "boolean",
            "default": false,
            "description": "Per-asset flag for JSON output of this asset entry."
          }
        }
      },
      "GeoPoint": {
        "type": "object",
        "description": "A geographic point in WGS84 decimal degrees. Both coordinates are\nrequired. Range checking (`lat` -90..90, `lon` -180..180) is enforced\ndownstream by OpenSearch.\n",
        "required": [
          "lat",
          "lon"
        ],
        "additionalProperties": false,
        "properties": {
          "lat": {
            "type": "number",
            "format": "double",
            "minimum": -90,
            "maximum": 90,
            "description": "Latitude in decimal degrees.",
            "example": 71.18507
          },
          "lon": {
            "type": "number",
            "format": "double",
            "minimum": -180,
            "maximum": 180,
            "description": "Longitude in decimal degrees.",
            "example": -25.2966
          }
        }
      },
      "Tag": {
        "type": "object",
        "properties": {
          "_id": {
            "description": "Server-issued numeric id of the tag. Returned on create and required\non every subsequent update so the server can detect concurrent edits.\n",
            "type": "number",
            "format": "int64",
            "minimum": 1,
            "nullable": true
          },
          "_version": {
            "type": "number",
            "format": "int64",
            "minimum": 1,
            "description": "The **_version** needs to be set to **1** for new objects and set to an\nincremented number on each object update. This is used to ensure that two\nclients do not overwrite data of the same object.\n"
          },
          "displayname": {
            "description": "Localized human-readable name of the tag. Shown wherever the front\nend surfaces a tag — picker, assignment list, facet, detail view.\n",
            "type": "object",
            "properties": {
              "de-DE": {
                "type": "string"
              },
              "en-US": {
                "type": "string"
              }
            },
            "example": {
              "de-DE": "Deutscher text",
              "en-US": "English text"
            }
          },
          "description": {
            "description": "Localized longer text explaining what the tag is for. Shown in admin\ntooltips and in the detail view next to the tag chip.\n",
            "type": "object",
            "properties": {
              "de-DE": {
                "type": "string"
              },
              "en-US": {
                "type": "string"
              }
            },
            "example": {
              "de-DE": "Deutscher text",
              "en-US": "English text"
            }
          },
          "frontend_prefs": {
            "type": "object",
            "additionalProperties": true,
            "description": "Frontend preferences can be any JSON Map with data used by applications. The\nconventions here is that each application can use its on key on the top level\nof this Map. Only this key may be modified by the application, foreign keys\nmust be kept unchanged.\n",
            "example": {
              "webfrontend": {
                "color": "red",
                "icon\"": "fa-ban"
              }
            }
          },
          "enabled": {
            "type": "boolean",
            "description": "Set to **true** if this tag is available?\n"
          },
          "is_default": {
            "type": "boolean",
            "description": "Set to **true** if the tag is set by default when creating new objects.\nThis is a frontend only flag.\n"
          },
          "sticky": {
            "type": "boolean",
            "description": "If set this tag cannot be removed by Pools which maintain their own tag lists.\n"
          },
          "type": {
            "type": "string",
            "enum": [
              "individual",
              "all_versions"
            ],
            "description": "Whether the tag applies to a single object version (`individual`) or\nacross all versions of an object (`all_versions`). Empty/omitted\ndefaults to `individual`.\n"
          },
          "reference": {
            "type": "string"
          },
          "shortname": {
            "type": "string"
          },
          "displaytype": {
            "type": "string",
            "enum": [
              "facet",
              "search",
              "detail",
              "editor",
              "hidden"
            ],
            "description": "How and where the tag is surfaced in the front end. One of `facet`,\n`search`, `detail`, `editor`, `hidden`. Empty/omitted defaults to\n`facet`.\n"
          }
        },
        "example": {
          "_id": 1,
          "displayname": {
            "de-DE": "Dogs"
          },
          "enabled": true,
          "displaytype": "detail",
          "sticky": true
        }
      },
      "TagGroup": {
        "type": "object",
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "taggroup"
            ],
            "description": "Always `taggroup`."
          },
          "_tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          },
          "taggroup": {
            "type": "object",
            "properties": {
              "_id": {
                "type": "number",
                "format": "int64",
                "minimum": 1,
                "nullable": true
              },
              "displayname": {
                "description": "Localized name of the tag group.",
                "type": "object",
                "properties": {
                  "de-DE": {
                    "type": "string"
                  },
                  "en-US": {
                    "type": "string"
                  }
                },
                "example": {
                  "de-DE": "Deutscher text",
                  "en-US": "English text"
                }
              },
              "reference": {
                "type": "string"
              },
              "shortname": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "checkbox",
                  "choice"
                ],
                "description": "A tag group of type **checkbox** can set multiple tags of that group. A tag group\nof type **choice** can only set one tag of that group.\n"
              }
            }
          }
        }
      },
      "ConfigList": {
        "type": "object",
        "properties": {
          "system": {
            "type": "object",
            "properties": {
              "defs": {
                "type": "array",
                "items": {
                  "type": "object",
                  "description": "Each item describes a config setting.",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "The unique name of this config"
                    },
                    "group": {
                      "type": "string",
                      "description": "The **group** sets the tab this config variable is in."
                    },
                    "parameters": {
                      "$ref": "#/components/schemas/ConfigParam"
                    },
                    "require_system_right": {
                      "type": "string",
                      "description": "System right which this config requires, e.g. \"system.root\" if it requires root rights."
                    },
                    "unauthenticated_visible": {
                      "type": "boolean",
                      "description": "If true, this config is visible to unauthenticated sessions (access token with no user)."
                    },
                    "unavailable": {
                      "type": "boolean",
                      "description": "If true, the feature this section configures is not available on\nthis instance (e.g. not included in the license). Frontends should\nrender the section greyed out but visible. Computed per request;\nomitted when false.\n"
                    }
                  }
                }
              }
            }
          },
          "plugin": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "description": "_key_ is the name of the plugin",
              "properties": {
                "defs": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "description": "Each item describes a config setting.",
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "The unique name of this config"
                      },
                      "group": {
                        "type": "string",
                        "description": "The **group** sets the tab this config variable is in."
                      },
                      "parameters": {
                        "$ref": "#/components/schemas/ConfigParam"
                      },
                      "require_system_right": {
                        "type": "string",
                        "description": "System right which this config requires, e.g. \"system.root\" if it requires root rights."
                      },
                      "unauthenticated_visible": {
                        "type": "boolean",
                        "description": "If true, this config is visible to unauthenticated sessions (access token with no user)."
                      },
                      "unavailable": {
                        "type": "boolean",
                        "description": "If true, the feature this section configures is not available on\nthis instance (e.g. not included in the license). Frontends should\nrender the section greyed out but visible. Computed per request;\nomitted when false.\n"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "License": {
        "type": "object",
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when this license was created."
          },
          "key": {
            "type": "string",
            "description": "UUID of license file, e.g., for blacklisting."
          },
          "issuer": {
            "type": "string",
            "description": "Name of the issuer of the license."
          },
          "holder": {
            "type": "string",
            "description": "Name of the holder of the license."
          },
          "type": {
            "type": "string",
            "description": "Type of license, such as \"subscription\" or \"buy\"."
          },
          "edition": {
            "type": "string",
            "description": "Edition of the license, such as \"workgroup\", \"department\", or \"organization\"."
          },
          "domains": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Must match fylr.externalURL, allows simple wildcard \"*\"."
          },
          "notes": {
            "type": "string",
            "description": "General notes for the customer."
          },
          "valid": {
            "type": "object",
            "properties": {
              "from": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Valid from this date, if empty already valid."
              },
              "to": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Valid to this date, if empty license does not expire."
              }
            }
          },
          "capabilities": {
            "type": "object"
          },
          "plugins": {
            "type": "object",
            "additionalProperties": {
              "description": "Set the capabilities for plugins."
            }
          }
        }
      },
      "task": {
        "type": "object",
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "task"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "datetime",
            "description": "UTC time of when the task was created.\n"
          },
          "updated_at": {
            "type": "string",
            "format": "datetime",
            "description": "UTC time of when the task was updated.\n"
          },
          "task": {
            "type": "object",
            "properties": {
              "_id": {
                "type": "number",
                "format": "int64",
                "description": "ID of the task. This is issued by the server.\n"
              },
              "_version": {
                "type": "number",
                "format": "int64",
                "description": "Version of the task. The version must be incremented when saving a new\nversion of the task. While the task is running, the server may perform\nupdates on the task object without incrementing the version.\n"
              },
              "task_module": {
                "type": "string",
                "description": "Name of the task module to run the task. Retrieve a list with `/api/v1/task/modules`.\n"
              },
              "task_params": {
                "type": "object",
                "additionalProperties": true,
                "description": "The task properties. The schema for this is defined by the task module.\n"
              },
              "task_timeout_sec": {
                "type": "number",
                "format": "int",
                "description": "When the task is run, this timeout is set. In case of a timeout the task will be in state `error`. Use `0` for no timeout.\n"
              },
              "description": {
                "type": "string",
                "description": "A user provided description of the task.\n"
              },
              "next_run_at": {
                "type": "string",
                "format": "datetime",
                "description": "The UTC time when the task will be started. It is possible that the task is run later that the given time (if other tasks are currently running), but not before. Set this to `null` to not execute this task. If a task is scheduled, the scheduler will update this property after the task has run.\n"
              },
              "frontend_prefs": {
                "type": "object",
                "additionalProperties": true,
                "description": "Provided by API using Apps. The top level key of the map should reflect the name of your App. Apps are required to store unknown keys (and data) along with their own contribution.\n"
              },
              "email": {
                "type": "object",
                "properties": {
                  "recipients": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "email": {
                          "type": "string",
                          "format": "email",
                          "description": "The email address of the recipient. Mails are send using the `To:` email header.\n"
                        },
                        "problems_only": {
                          "type": "boolean",
                          "description": "If set, emails are only sent if the task finished with a state other than `done`.\n"
                        }
                      }
                    }
                  }
                }
              },
              "schedules": {
                "type": "array",
                "items": {
                  "type": "object",
                  "description": "A schedule sets criterias to repeatedly start task or jobs. All defined criterias need to be met in order for a schedule to run.\n",
                  "properties": {
                    "days_of_month": {
                      "type": "array",
                      "items": {
                        "type": "number",
                        "format": "int",
                        "description": "The day of the month when this schedule should run.\n"
                      }
                    },
                    "weekdays": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "sunday",
                          "monday",
                          "tuesday",
                          "wednesday",
                          "thursday",
                          "friday",
                          "saturday"
                        ]
                      },
                      "description": "The weekday when this schedule should run.\n"
                    },
                    "hours": {
                      "type": "array",
                      "items": {
                        "type": "number",
                        "format": "int",
                        "description": "The hour when this schedule should run. Range `0`-`23`.\n"
                      }
                    },
                    "minutes": {
                      "type": "array",
                      "items": {
                        "type": "number",
                        "format": "int",
                        "description": "The minute when this schedule should run. Range `0`-`59`.\n"
                      }
                    },
                    "timezone": {
                      "type": "string",
                      "description": "The timezone this schedule should be run in. Valid names are in [IANA format](https://www.iana.org/time-zones).\n"
                    }
                  }
                }
              },
              "state": {
                "type": "object",
                "readOnly": true,
                "additionalProperties": true,
                "description": "Stores the state of a task. This can be used by the task module to continue interrupted work or otherwise. The data is provided over the API, so frontends may use it.\n"
              },
              "status": {
                "type": "string",
                "readOnly": true,
                "enum": [
                  "new",
                  "running",
                  "done",
                  "canceled",
                  "error"
                ],
                "description": "`status` is set by the **fylr** task runner.\n"
              },
              "status_percent": {
                "type": [
                  "number",
                  "null"
                ],
                "readOnly": true,
                "format": "int",
                "minimum": 0,
                "maximum": 100,
                "description": "If supported by the task runner, a number from `0` to `100` (percent) indicating the progress of a task in state `running`. This can be `null` if the task module has not started updating this yet, or it is not supported by the task module. Frontends should only show and use this if it is not `null`.\n"
              },
              "status_msg": {
                "type": "string",
                "readOnly": true,
                "description": "If the status is `error` or `canceled`, the status message gives more information.\n"
              },
              "run_started_at": {
                "type": "string",
                "format": "datetime",
                "readOnly": true,
                "description": "UTC time when the last run of the task was started. It is set to `null` when the task re-starts.\n"
              },
              "run_canceled_at": {
                "type": "string",
                "format": "datetime",
                "readOnly": true,
                "description": "UTC time when the last run of the task was canceled. It is set to `null` when the task re-starts.\n"
              },
              "run_finished_at": {
                "type": "string",
                "format": "datetime",
                "readOnly": true,
                "description": "UTC time when the last run of the task has finished. It is set to `null` when the task re-starts.\n"
              }
            }
          },
          "_user": {
            "type": "object",
            "readOnly": true,
            "description": "The user that created the task. The task is run as this user. This is a\nflat user object; only the creating user (or a `system.root` user) can\nretrieve the task.\n",
            "properties": {
              "_id": {
                "type": "number",
                "format": "int64",
                "description": "The id of the user. It is automatically assigned.\n"
              },
              "_version": {
                "type": "number",
                "format": "int64",
                "description": "The version of the user record.\n"
              },
              "_generated_displayname": {
                "type": "string",
                "description": "The generated displayname of the user. This uses `login` and `email`.\n"
              }
            }
          }
        },
        "example": {
          "task": {
            "_id": 1,
            "_version": 2,
            "task_module": "sleep",
            "description": "henk is super",
            "task_params": {
              "runtime": 5
            },
            "task_timeout_sec": 100,
            "next_run_at": "2026-05-30T12:00:10Z",
            "status": "new"
          },
          "_user": {
            "_generated_displayname": "root"
          }
        }
      },
      "file": {
        "type": "object",
        "properties": {
          "_id": {
            "type": "number",
            "format": "int64",
            "minimum": 1,
            "description": "The `_id` is **created** _when_ a file is uploaded into the fylr server.\n"
          },
          "eas_parent_id": {
            "type": "number",
            "format": "int64",
            "nullable": true,
            "description": "The `eas_parent_id` is the id of the file this file is derived from. When using **/api/produce**, the newly produced files will get the parent id set to the file they are produced from.\n"
          },
          "reference": {
            "type": "string",
            "nullable": true,
            "description": "If set, this reference string is a unique string identifying the file. If the reference contains a `sha244:\u003chash\u003e` or `sha256:\u003chash\u003e`, the provided hash can be checked against the file's checksum using an action triggerable in **/inspect/files**. Other parts of the reference can be added but must be separated by `:`.\n"
          },
          "upload_user": {
            "type": "object",
            "description": "The user who uploaded this file into the system. If the upload happens via Hotfolder, the uploader is the owner of the upload collection.\n",
            "properties": {
              "_basetype": {
                "type": "string",
                "default": "user",
                "description": "**\"user\"**. More info can be found [here](./user.md) [here2](../system-data-types/user.md) [here3](../../for-developers/system-data-types/user.md) [here4](https://docs.fylr.io/for-developers/system-data-types/user)\n"
              },
              "user": {
                "type": "object",
                "description": "This will show a short representation of [user](https://docs.fylr.io/for-developers/system-data-types/user).\n"
              }
            }
          },
          "date_uploaded": {
            "type": "string",
            "format": "timestamp",
            "description": "The UTC timestamp when this file was uploaded.\n"
          },
          "best_date": {
            "type": "string",
            "format": "timestamp",
            "description": "Best date is a compiled UTC timestamp from the technical metadata. **fylr** uses the first set date from `technical_metadata.date_time_original`, `technical_metadata.create_date`, `date_uploaded`.\n"
          },
          "filesize": {
            "type": "number",
            "format": "int64",
            "description": "The file size in bytes.\n"
          },
          "status": {
            "type": "string",
            "description": "The status of the file. Known states are: `pending`, `processing`, `sync`, `done`, `failed`. Files and renditions can be accessed in status `sync` and `done`. Only files in state `done` can be exported.\n"
          },
          "last_status_at": {
            "type": "string",
            "format": "timestamp",
            "description": "The UTC timestamp when the last status change was last written to the database.\n"
          },
          "extension": {
            "type": "string",
            "description": "The compiled extension of the file. This is matched by parsing available recipes at the time of the metadata generation. Extensions are matched by longer length first. So for a file `flower.webdvd.zip` the extension matched would be `.webdvd.zip` and not `.zip` if there is an available recipe.\n"
          },
          "class": {
            "type": "string",
            "description": "The compiled class of the file. The classes are set by the recipe. Standard recipes of fylr include `image`, `audio`, `office`, `video`. The fylr frontend uses the class to pick the general player to view the file. A class `unknown` is assigned if no matching recipe was found but the upload accepts _unknown types_.\n"
          },
          "class_version_status": {
            "type": "string",
            "description": "A compiled concatenation of `class`, `version` and `status`, joined by `.`. This is used for aggregations of file status.\n"
          },
          "class_extension": {
            "type": "string",
            "description": "A compiled concatenation of `class`, `version`, joined by `.`. This is used for aggregations of files\n"
          },
          "is_original": {
            "type": "boolean",
            "description": "Set to true if the file is an original. It is false if the file is a generated or uploaded rendition. Produced files are registered as originals underneath the original they are produced from.\n"
          },
          "hash": {
            "type": "string",
            "description": "The `hash` is a non unique identifier of the file. For remote files, it is the [**md5sum**](https://en.wikipedia.org/wiki/Md5sum) of the URL, for local files it is the [**SHA-256**](https://en.wikipedia.org/wiki/SHA-2) of the binary file data. It is calculated together with the metadata for the file and a copy of `technical_metadata.sha256_hash`. The `hash` is used for duplicate detection.\n"
          },
          "technical_metadata": {
            "type": "object",
            "description": "Intrinsic technical properties of the file, serialized as a **flat**\nkey/value object (a single level — this is *not* the namespaced groups\nmap found in `metadata`). The well-known, fylr-computed keys are typed by\nthe `technical_metadata` component below (`width`, `height`, `dpi`,\n`colorspace`, `format`, `dimensions`, `gps_location`, ...).\n\nIn addition, metadata recipes and plugins may inject **arbitrary extra\nkeys** (the value of each is recipe-defined: string, number, boolean,\nnested object or array). Those extra keys are covered by\n`additionalProperties` and are intentionally open because they originate\nfrom external extractors (exiftool / plugins) and are not enumerable in\ncode.\n\nSee [Technical Metadata](https://docs.fylr.io/for-developers/system-data-types/file#technical_metadata)\nfor details.\n",
            "allOf": [
              {
                "$ref": "#/components/schemas/technical_metadata"
              }
            ],
            "additionalProperties": true,
            "example": {
              "width": 1920,
              "height": 1440,
              "dpi": 1,
              "colorspace": "rgb",
              "format": "landscape",
              "mime_type": "image/jpeg",
              "file_type_extension": "jpg",
              "filesize": 885714,
              "dimensions": {
                "width": 1920,
                "height": 1440,
                "unit": "px"
              },
              "sha256_hash": "2f19a9fd4ad56217899e275c0177a14e40a3061cc96ea0747ce973877aead14c",
              "huhu": {
                "gut": "sieht torsten custom:und henk"
              }
            }
          },
          "compiled": {
            "type": "string",
            "description": "A compiled version of the metadata for this file. For images this looks like this: `\tJPG, 1920 x 1285 px, 569.5 kB`.\n"
          },
          "compiled_props": {
            "type": "object",
            "description": "A fielded version of `compiled`. Frontends can use this to beatify the compiled output of the metadata.\n",
            "properties": {
              "extension": {
                "type": "string",
                "description": "The upper cased version of the `extension`.\n"
              },
              "dimensions": {
                "type": "string",
                "description": "The rendered dimensions for this file. This may include a unit. For page sizes European paper sizes like A4 will be recognised.\n"
              },
              "duration": {
                "type": "string",
                "description": "Runtime of the audio or video file.\n"
              },
              "pages": {
                "type": "string",
                "description": "The number of pages followed by a ` p.`. Frontends may localize this manually.\n"
              }
            }
          },
          "_mapped_metadata": {
            "description": "A rendered **object record** mapped from this file's metadata, used to\ncreate an object from a pre-configured metadata mapping. It is *not*\nfree-form: it is a full fylr object (the same shape as a `/db` object\nrecord) produced via the configured mapping for the upload collection,\nobject type, pool and request.\n\nIt is only present in the response when the `/api/eas` request asks for a\nmapping (`mapping=standard` or a mapping id) **and** a mapping is\nresolved; otherwise it is omitted. The nested object keyed by the object\ntype name holds the mapped content fields.\n",
            "allOf": [
              {
                "$ref": "#/components/schemas/DbObject"
              }
            ]
          },
          "metadata": {
            "type": "object",
            "properties": {
              "groupnames": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Sorted list of metadata group names found in `groups`.\n"
              },
              "groups": {
                "type": "object",
                "additionalProperties": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "value": {
                        "description": "The value can be any type\n"
                      },
                      "print": {
                        "type": "string",
                        "description": "A printable version of `value`\n"
                      },
                      "name": {
                        "type": "string",
                        "description": "The name of the attribute.\n"
                      },
                      "group": {
                        "type": "string",
                        "description": "The group name of the attribute\n"
                      }
                    }
                  }
                }
              }
            }
          },
          "original_filepath": {
            "type": "string",
            "description": "Filename of the file as set during the upload. On Windows, this can contain drive letters and backslashes.\n"
          },
          "original_filename": {
            "type": "string",
            "description": "The filename as set by `original_filepath` minus the path.\n"
          },
          "original_filename_basename": {
            "type": "string",
            "description": "The filename as set by `original_filepath` minus the path and the detected `extension`.\n"
          },
          "versions": {
            "type": "object",
            "description": "Map of rendition name to file version. Depending on the user's asset\nrights (`asset_show` / `asset_download`), not all versions are\naccessible, so some may be absent. The key `original` refers to the\nuploaded original; produced and custom renditions use their own version\nnames. When present but empty the value is rendered as `{}`.\n",
            "additionalProperties": {
              "$ref": "#/components/schemas/file_version"
            }
          },
          "_duplicates": {
            "type": "array",
            "description": "If set, this attribute can hold an array of duplicates.\n",
            "items": {
              "type": "object",
              "properties": {
                "_id": {
                  "type": "number",
                  "format": "int64",
                  "description": "The `file._id` of the detected duplicate."
                },
                "certainty": {
                  "type": "number",
                  "format": "float64",
                  "description": "The certainty of the duplicate detection in percent. A value of 1.0 means 100%. Currently **fylr** can only detect exact same files (as per file hash).\n"
                },
                "linked_system_objects": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "_system_object_id": {
                        "type": "number",
                        "format": "int64",
                        "description": "The `_system_object_id` of the object using the duplicate file.\n"
                      },
                      "_column_id": {
                        "type": "number",
                        "format": "int64",
                        "description": "The column API id of the column holding the duplicate file.\n"
                      }
                    }
                  }
                }
              }
            }
          },
          "_linked_objects": {
            "type": "array",
            "description": "When a file is uploaded and linked to a collection via\n[`/api/eas`](https://docs.fylr.io/for-developers/api/endpoints/api-eas),\nthe attribute contains a list of objects created based on the upload\nsettings of that collection.\n",
            "items": {
              "type": "object",
              "properties": {
                "_system_object_id": {
                  "type": "number",
                  "format": "int64",
                  "description": "The `_system_object_id` of the object created.\n"
                },
                "_version": {
                  "type": "number",
                  "format": "int64",
                  "description": "The `_version` of the object created or updated. An upload may\nupdate an existing object if a version or series detection added a\nfile to an existing nested or an existing file array.\n"
                }
              }
            }
          },
          "preferred": {
            "type": "boolean",
            "description": "This may be set if the file is in the context of an object. If set,\npreferred indicates that this version is the preferred one in a list of\nother versions.\n"
          },
          "name": {
            "type": "string",
            "description": "Custom name of the file. This is set in the relation to the object. When\nretrieving the file via\n[`/api/eas`](https://docs.fylr.io/for-developers/api/endpoints/api-eas).\n"
          },
          "frontend_prefs": {
            "type": "object",
            "additionalProperties": true,
            "description": "Set only in relation to an object. This map can contain custom attributes and values.\n"
          },
          "lookup:_id": {
            "type": "object",
            "properties": {
              "reference": {
                "type": "string",
                "description": "The `reference` of the file to look up.\n"
              }
            }
          }
        }
      },
      "technical_metadata": {
        "type": "object",
        "properties": {
          "aspect_ratio": {
            "type": "number",
            "format": "float64"
          },
          "audio_codec": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "blurhash": {
            "type": "string"
          },
          "camera_scanner": {
            "type": "string"
          },
          "colordepth": {
            "type": "number",
            "format": "int"
          },
          "colorprofile": {
            "type": "string"
          },
          "colorspace": {
            "type": "string"
          },
          "create_date": {
            "type": "string"
          },
          "date_time_original": {
            "type": "string"
          },
          "dpi": {
            "type": "number",
            "format": "int"
          },
          "duration": {
            "type": "number",
            "format": "double",
            "description": "Media duration in seconds; may be fractional."
          },
          "filesize": {
            "type": "number",
            "format": "int64"
          },
          "file_type_extension": {
            "type": "string"
          },
          "format": {
            "type": "string",
            "description": "The format of the file: `landscape`, `portrait` or `square`.\n"
          },
          "gps_location": {
            "type": "object",
            "properties": {
              "longitude": {
                "type": "number",
                "format": "float64"
              },
              "latitude": {
                "type": "number",
                "format": "float64"
              },
              "altitude": {
                "type": "number",
                "format": "float64"
              }
            }
          },
          "has_clipping_path": {
            "type": "boolean"
          },
          "height": {
            "type": "number",
            "format": "int"
          },
          "max_dimension": {
            "type": "number",
            "format": "int"
          },
          "mime_type": {
            "type": "string"
          },
          "orientation": {
            "type": "string"
          },
          "pages": {
            "type": "number",
            "format": "int"
          },
          "num_glyphs": {
            "type": "number",
            "format": "int"
          },
          "projection_type": {
            "type": "string",
            "description": "360° projection of a spherical video or panoramic image, e.g.\n`equirectangular`. Compiled from the Spherical Video metadata\n(V1 XML or V2 `sv3d`/Matroska `Projection` via ffprobe) for videos\nand the XMP GPano tags for images. Absent for flat media.\n"
          },
          "samples_per_pixel": {
            "type": "number",
            "format": "int",
            "description": "Number of samples (channels) per pixel of a TIFF, e.g. `7` for RGB plus\n4 extra channels (alpha, spot colors) as written by Photoshop.\n"
          },
          "sha256_hash": {
            "type": "string"
          },
          "video_codec": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "width": {
            "type": "number",
            "format": "int"
          },
          "dimensions": {
            "type": "object",
            "properties": {
              "width": {
                "type": "number",
                "format": "float64"
              },
              "height": {
                "type": "number",
                "format": "float64"
              },
              "unit": {
                "type": "string"
              }
            }
          }
        }
      },
      "file_version": {
        "type": "object",
        "properties": {
          "_id": {
            "type": "string"
          },
          "aspect_ratio": {
            "type": "string"
          },
          "blurhash": {
            "type": "string"
          },
          "class": {
            "type": "string"
          },
          "class_extension": {
            "type": "string"
          },
          "date_created": {
            "type": "string"
          },
          "_download_allowed": {
            "type": "boolean"
          },
          "_show_allowed": {
            "type": "boolean"
          },
          "dpi": {
            "type": "string"
          },
          "extension": {
            "type": "string"
          },
          "filesize": {
            "type": "string"
          },
          "hash": {
            "type": "string"
          },
          "height": {
            "type": "string"
          },
          "last_status_at": {
            "type": "string"
          },
          "orientation": {
            "type": "string"
          },
          "percent_done": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "zoom_url": {
            "type": "string"
          },
          "iiif_url": {
            "type": "string"
          },
          "deep_link_url": {
            "type": "string"
          },
          "watermark": {
            "type": "string"
          },
          "width": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "technical_metadata": {
            "type": "string"
          }
        }
      },
      "user_config": {
        "type": "object",
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "user"
            ]
          },
          "user": {
            "type": "object",
            "properties": {
              "_id": {
                "type": "number",
                "format": "int64",
                "description": "The id of the user.\n"
              }
            }
          }
        }
      },
      "response_202": {
        "type": "object",
        "additionalProperties": false,
        "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
        "required": [
          "tasks"
        ],
        "properties": {
          "tasks": {
            "type": "array",
            "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title",
                "message",
                "buttons"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "description": "Short, localized heading for the confirmation."
                },
                "message": {
                  "type": "string",
                  "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                },
                "form": {
                  "type": "array",
                  "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "label",
                      "type",
                      "name",
                      "options",
                      "horizontal"
                    ],
                    "properties": {
                      "label": {
                        "type": "string",
                        "description": "Localized label for the field. May be empty."
                      },
                      "type": {
                        "type": "string",
                        "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                      },
                      "name": {
                        "type": "string",
                        "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                      },
                      "options": {
                        "type": "array",
                        "description": "The selectable choices for this field.",
                        "items": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "text",
                            "value",
                            "disabled"
                          ],
                          "properties": {
                            "text": {
                              "type": "string",
                              "description": "Localized label shown for this choice."
                            },
                            "value": {
                              "type": "string",
                              "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                            },
                            "disabled": {
                              "type": "boolean",
                              "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                            }
                          }
                        }
                      },
                      "horizontal": {
                        "type": "boolean",
                        "description": "Display hint — lay the options out in a row."
                      }
                    }
                  }
                },
                "buttons": {
                  "type": "array",
                  "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "text": {
                        "type": "string",
                        "description": "Localized button label."
                      },
                      "hidden": {
                        "type": "boolean",
                        "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                      },
                      "name": {
                        "type": "string",
                        "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                      },
                      "value": {
                        "type": "string",
                        "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "DbPost202": {
        "allOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
            "required": [
              "tasks"
            ],
            "properties": {
              "tasks": {
                "type": "array",
                "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "title",
                    "message",
                    "buttons"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Short, localized heading for the confirmation."
                    },
                    "message": {
                      "type": "string",
                      "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                    },
                    "form": {
                      "type": "array",
                      "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "label",
                          "type",
                          "name",
                          "options",
                          "horizontal"
                        ],
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Localized label for the field. May be empty."
                          },
                          "type": {
                            "type": "string",
                            "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                          },
                          "options": {
                            "type": "array",
                            "description": "The selectable choices for this field.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "text",
                                "value",
                                "disabled"
                              ],
                              "properties": {
                                "text": {
                                  "type": "string",
                                  "description": "Localized label shown for this choice."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                                },
                                "disabled": {
                                  "type": "boolean",
                                  "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                                }
                              }
                            }
                          },
                          "horizontal": {
                            "type": "boolean",
                            "description": "Display hint — lay the options out in a row."
                          }
                        }
                      }
                    },
                    "buttons": {
                      "type": "array",
                      "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "Localized button label."
                          },
                          "hidden": {
                            "type": "boolean",
                            "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                          },
                          "value": {
                            "type": "string",
                            "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "description": "The `202` body of `POST /db/{objecttype}` — a `response_202` confirm-and-resend\ntask. The example shows the access-revocation case; transition and reverse-pool\ncases use the same shape with `confirmTransition` / `reverse_pool_changed_mode`.\n",
        "example": {
          "tasks": [
            {
              "title": "Save record",
              "message": "By saving this record, you will no longer be able to edit this record. Do you want to proceed?",
              "buttons": [
                {
                  "text": "Save",
                  "name": "revoke",
                  "value": "yes"
                }
              ]
            }
          ]
        }
      },
      "DbDelete202": {
        "allOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
            "required": [
              "tasks"
            ],
            "properties": {
              "tasks": {
                "type": "array",
                "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "title",
                    "message",
                    "buttons"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Short, localized heading for the confirmation."
                    },
                    "message": {
                      "type": "string",
                      "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                    },
                    "form": {
                      "type": "array",
                      "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "label",
                          "type",
                          "name",
                          "options",
                          "horizontal"
                        ],
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Localized label for the field. May be empty."
                          },
                          "type": {
                            "type": "string",
                            "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                          },
                          "options": {
                            "type": "array",
                            "description": "The selectable choices for this field.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "text",
                                "value",
                                "disabled"
                              ],
                              "properties": {
                                "text": {
                                  "type": "string",
                                  "description": "Localized label shown for this choice."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                                },
                                "disabled": {
                                  "type": "boolean",
                                  "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                                }
                              }
                            }
                          },
                          "horizontal": {
                            "type": "boolean",
                            "description": "Display hint — lay the options out in a row."
                          }
                        }
                      }
                    },
                    "buttons": {
                      "type": "array",
                      "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "Localized button label."
                          },
                          "hidden": {
                            "type": "boolean",
                            "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                          },
                          "value": {
                            "type": "string",
                            "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "description": "The `202` body of `DELETE /db/{objecttype}` — a `response_202` confirm-and-resend\ntask. The example shows the delete-policy case (objects still linked from\nothers); the client re-sends with the chosen `delete_policy`.\n",
        "example": {
          "tasks": [
            {
              "title": "Confirmation",
              "message": "The record you are trying to delete is referenced in other records. Please choose how you want to proceed.",
              "form": [
                {
                  "label": "",
                  "type": "options",
                  "name": "delete_policy",
                  "horizontal": false,
                  "options": [
                    {
                      "text": "Delete 3",
                      "value": "remove",
                      "disabled": false
                    },
                    {
                      "text": "Delete 3 and unlink 2",
                      "value": "setnull",
                      "disabled": false
                    },
                    {
                      "text": "Create collection with records to be deleted",
                      "value": "create_collection",
                      "disabled": false
                    }
                  ]
                }
              ],
              "buttons": [
                {
                  "text": "Confirm",
                  "name": "confirm",
                  "value": "delete"
                }
              ]
            }
          ]
        }
      },
      "ConfigPost202": {
        "allOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
            "required": [
              "tasks"
            ],
            "properties": {
              "tasks": {
                "type": "array",
                "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "title",
                    "message",
                    "buttons"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Short, localized heading for the confirmation."
                    },
                    "message": {
                      "type": "string",
                      "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                    },
                    "form": {
                      "type": "array",
                      "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "label",
                          "type",
                          "name",
                          "options",
                          "horizontal"
                        ],
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Localized label for the field. May be empty."
                          },
                          "type": {
                            "type": "string",
                            "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                          },
                          "options": {
                            "type": "array",
                            "description": "The selectable choices for this field.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "text",
                                "value",
                                "disabled"
                              ],
                              "properties": {
                                "text": {
                                  "type": "string",
                                  "description": "Localized label shown for this choice."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                                },
                                "disabled": {
                                  "type": "boolean",
                                  "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                                }
                              }
                            }
                          },
                          "horizontal": {
                            "type": "boolean",
                            "description": "Display hint — lay the options out in a row."
                          }
                        }
                      }
                    },
                    "buttons": {
                      "type": "array",
                      "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "Localized button label."
                          },
                          "hidden": {
                            "type": "boolean",
                            "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                          },
                          "value": {
                            "type": "string",
                            "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "description": "The `202` body of `POST /config` (and of a sub-path config patch) — a\n`response_202` confirm-and-resend task. The example shows the savable-config-\nerror case (here an LDAP connection that does not dial): resend with\n`save=ignore_errors` to persist despite the recoverable error. The\nlanguage-change case uses the same shape with a `form` field named `reindex`\n(options `skip` / `reindex` / `reindex_block`) and a button `confirm`=`yes`.\n",
        "example": {
          "tasks": [
            {
              "title": "Basis-Konfiguration",
              "message": "In der Konfiguration gibt es folgende Probleme:\n\n* Unable to connect: ...\n\nBestätigen Sie, um trotzdem zu speichern.\n",
              "buttons": [
                {
                  "text": "Speichern",
                  "name": "save",
                  "value": "ignore_errors"
                }
              ]
            }
          ]
        }
      },
      "PluginManageApi": {
        "type": "object",
        "description": "A single plugin as seen by the management API (`/plugin/manage`).\nCarries the stored plugin row (id, name, enabled flag, source) plus\nthe parsed `manifest`. Used both as the request body of\n`PUT`/`POST /plugin/manage` and as their response.\n\nOn create (`PUT`) the body must NOT carry an `id`; on update\n(`POST /plugin/manage/{id}`) the body `id` must match the path `{id}`.\n",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "description": "Numeric id of the stored plugin. Assigned by **fylr** on create;\nmust be absent (or `0`) in a `PUT` create body, and must match the\npath `{id}` in a `POST` update body.\n"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unique plugin name (matches the manifest `name:`). Read-only in\nresponses; derived from the uploaded plugin on create.\n"
          },
          "enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the plugin is enabled. A freshly uploaded plugin is\ncreated disabled (`false`); enable it with an update.\n"
          },
          "auto_added": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "`true` when the plugin was discovered and registered automatically\n(e.g. from the plugins directory) rather than uploaded via the API.\n"
          },
          "path": {
            "type": [
              "string",
              "null"
            ],
            "description": "Filesystem path the plugin is loaded from, if any."
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Source URL the plugin is fetched from when `type` is `url`.\n"
          },
          "type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Source type of the plugin. `zip` for a plugin uploaded as a ZIP\nasset (`zip_file`), `url` for one fetched from a remote `url`.\n"
          },
          "zip_file": {
            "type": [
              "object",
              "null"
            ],
            "description": "The uploaded plugin ZIP, referenced by file id. On create from an\nupload, send `{ \"_id\": \u003cfileId\u003e }` of a previously uploaded asset.\n",
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64",
                "description": "File id of the uploaded plugin ZIP asset."
              }
            },
            "additionalProperties": true
          },
          "update_policy": {
            "type": [
              "string",
              "null"
            ],
            "description": "Update policy stored for the plugin (controls how/when **fylr**\nrefreshes the plugin from its source).\n"
          },
          "manifest": {
            "$ref": "#/components/schemas/PluginBase",
            "description": "The parsed plugin manifest plus the request-time asset URLs\n(`base_url`, `plugin_url`).\n"
          },
          "last_checked_at": {
            "type": "string",
            "format": "date-time",
            "description": "When **fylr** last checked the plugin source for updates."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Last-update timestamp."
          }
        },
        "example": {
          "type": "zip",
          "enabled": false
        }
      },
      "PluginManageList": {
        "type": "object",
        "description": "Response of `GET /plugin/manage` — the full list of installed\nplugins (enabled and disabled) as seen by the management API.\n",
        "required": [
          "plugins"
        ],
        "properties": {
          "plugins": {
            "type": "array",
            "description": "One entry per installed plugin.",
            "items": {
              "$ref": "#/components/schemas/PluginManageApi"
            }
          }
        }
      },
      "PluginDeleteAck": {
        "type": "object",
        "description": "Response of `DELETE /plugin/manage/{id}` — confirms the plugin was\nremoved.\n",
        "required": [
          "acknowledged"
        ],
        "properties": {
          "acknowledged": {
            "type": "boolean",
            "description": "Always `true` when the plugin was deleted.",
            "enum": [
              true
            ]
          }
        },
        "example": {
          "acknowledged": true
        }
      },
      "UserPost202": {
        "allOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
            "required": [
              "tasks"
            ],
            "properties": {
              "tasks": {
                "type": "array",
                "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "title",
                    "message",
                    "buttons"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Short, localized heading for the confirmation."
                    },
                    "message": {
                      "type": "string",
                      "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                    },
                    "form": {
                      "type": "array",
                      "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "label",
                          "type",
                          "name",
                          "options",
                          "horizontal"
                        ],
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Localized label for the field. May be empty."
                          },
                          "type": {
                            "type": "string",
                            "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                          },
                          "options": {
                            "type": "array",
                            "description": "The selectable choices for this field.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "text",
                                "value",
                                "disabled"
                              ],
                              "properties": {
                                "text": {
                                  "type": "string",
                                  "description": "Localized label shown for this choice."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                                },
                                "disabled": {
                                  "type": "boolean",
                                  "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                                }
                              }
                            }
                          },
                          "horizontal": {
                            "type": "boolean",
                            "description": "Display hint — lay the options out in a row."
                          }
                        }
                      }
                    },
                    "buttons": {
                      "type": "array",
                      "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "Localized button label."
                          },
                          "hidden": {
                            "type": "boolean",
                            "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                          },
                          "value": {
                            "type": "string",
                            "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "description": "The `202` body of `POST` / `PUT /user` — a `response_202` confirm-and-resend\ntask raised when a user in the payload sets a password that does not satisfy\nthe configured password-complexity rules. The task has no `form`; its button\ncarries `confirm=ignore_password_requirements`. To save the user anyway, the\nclient re-sends the **same** request with the query parameter\n`confirm=ignore_password_requirements` appended. (For this operation the\n`confirm` parameter is operative — unlike the generic `confirm` button the\nserver otherwise ignores.) The `%(requirement)s` placeholder in the message\nis filled with the configured password hint.\n",
        "example": {
          "tasks": [
            {
              "title": "Password Change",
              "message": "One or more user passwords do not match the configured requirements: %(requirement)s Should the password be saved anyway?",
              "buttons": [
                {
                  "text": "Save",
                  "name": "confirm",
                  "value": "ignore_password_requirements"
                }
              ]
            }
          ]
        }
      },
      "UserDelete202": {
        "allOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
            "required": [
              "tasks"
            ],
            "properties": {
              "tasks": {
                "type": "array",
                "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "title",
                    "message",
                    "buttons"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Short, localized heading for the confirmation."
                    },
                    "message": {
                      "type": "string",
                      "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                    },
                    "form": {
                      "type": "array",
                      "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "label",
                          "type",
                          "name",
                          "options",
                          "horizontal"
                        ],
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Localized label for the field. May be empty."
                          },
                          "type": {
                            "type": "string",
                            "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                          },
                          "options": {
                            "type": "array",
                            "description": "The selectable choices for this field.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "text",
                                "value",
                                "disabled"
                              ],
                              "properties": {
                                "text": {
                                  "type": "string",
                                  "description": "Localized label shown for this choice."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                                },
                                "disabled": {
                                  "type": "boolean",
                                  "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                                }
                              }
                            }
                          },
                          "horizontal": {
                            "type": "boolean",
                            "description": "Display hint — lay the options out in a row."
                          }
                        }
                      }
                    },
                    "buttons": {
                      "type": "array",
                      "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "Localized button label."
                          },
                          "hidden": {
                            "type": "boolean",
                            "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                          },
                          "value": {
                            "type": "string",
                            "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "description": "The `202` body of `DELETE /user/{id}` — a `response_202` confirm-and-resend\ntask raised when no `delete_policy` was supplied (and the instance default is\n`ask`). The task's `form` field `delete_policy` lists the allowed policies;\nthe client re-sends the request with the chosen `delete_policy` value. The\ngeneric submit button carries `confirm=delete`, which the server ignores —\nthe operative parameter is `delete_policy`. The example shows a single\narchived user: the offered options are `delete` and `unarchive`.\n",
        "example": {
          "tasks": [
            {
              "title": "Confirmation",
              "message": "Users can be archived or deleted. When archiving, the information is retained in the change history, but not when deleting. If configured, users are pseudonymized during archiving. When archiving, the user's collections are deleted and cannot be restored.",
              "form": [
                {
                  "label": "",
                  "type": "options",
                  "name": "delete_policy",
                  "horizontal": false,
                  "options": [
                    {
                      "text": "Delete user",
                      "value": "delete",
                      "disabled": false
                    },
                    {
                      "text": "Unarchive user",
                      "value": "unarchive",
                      "disabled": false
                    }
                  ]
                }
              ],
              "buttons": [
                {
                  "text": "Confirm",
                  "name": "confirm",
                  "value": "delete"
                }
              ]
            }
          ]
        }
      },
      "Collection202": {
        "allOf": [
          {
            "$ref": "#/components/schemas/response_202"
          }
        ],
        "description": "Returned (HTTP 202) by a collection write that shares rights when the\ncollection's `_owner` lacks a grantable right for one of the linked objects\nand the caller has `BAG_ACL`. The task offers to store the collection anyway\nwith sharing disabled: re-send the same request with `allow_invalid_acl=true`\n(the button's `name`=`value`). When stored this way the collection is flagged\n`_invalid_acl: true` and its ACL is not applied.\n",
        "example": {
          "tasks": [
            {
              "title": "Collection",
              "message": "The owner \"alice\" of the collection \"Marketing\" does not have the\npermission \"read\" for record #4711 in order to share the collection.\nYou can save the collection anyways, but sharing for this collection\nwill be disabled completely.",
              "buttons": [
                {
                  "text": "Save",
                  "name": "allow_invalid_acl",
                  "value": "true"
                }
              ]
            }
          ]
        }
      },
      "ObjecttypePost202": {
        "allOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
            "required": [
              "tasks"
            ],
            "properties": {
              "tasks": {
                "type": "array",
                "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "title",
                    "message",
                    "buttons"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Short, localized heading for the confirmation."
                    },
                    "message": {
                      "type": "string",
                      "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                    },
                    "form": {
                      "type": "array",
                      "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "label",
                          "type",
                          "name",
                          "options",
                          "horizontal"
                        ],
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Localized label for the field. May be empty."
                          },
                          "type": {
                            "type": "string",
                            "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                          },
                          "options": {
                            "type": "array",
                            "description": "The selectable choices for this field.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "text",
                                "value",
                                "disabled"
                              ],
                              "properties": {
                                "text": {
                                  "type": "string",
                                  "description": "Localized label shown for this choice."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                                },
                                "disabled": {
                                  "type": "boolean",
                                  "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                                }
                              }
                            }
                          },
                          "horizontal": {
                            "type": "boolean",
                            "description": "Display hint — lay the options out in a row."
                          }
                        }
                      }
                    },
                    "buttons": {
                      "type": "array",
                      "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "Localized button label."
                          },
                          "hidden": {
                            "type": "boolean",
                            "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                          },
                          "value": {
                            "type": "string",
                            "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "description": "Confirm-and-resend payload (HTTP 202) returned by\n`POST /api/v1/objecttype` when the save needs confirmation. The client\nre-sends the **same** request body with the query parameter implied by\nthe task appended:\n\n  * `allow_invalid_acl=true` — proceed with an ACL change that would\n    invalidate a collection (button `allow_invalid_acl`).\n  * `background_invalid_acl=true` — run the ACL revalidation as a\n    background task after a synchronous timeout (button\n    `background_invalid_acl`).\n  * `confirm=resync` / `confirm=skip` — recompute or skip renditions\n    when a watermark / caption change requires it (form field\n    `confirm`).\n\nSee the `confirm`, `allow_invalid_acl`, `background_invalid_acl` and\n`background_invalid_acl_timelimit` query parameters on the operation.\n",
        "example": {
          "tasks": [
            {
              "title": "Collection",
              "message": "The owner \"...\" of the collection \"...\" does not have the\npermission \"...\" for record #... in order to share the\ncollection. You can save the collection anyways, but sharing\nfor this collection will be disabled completely.",
              "buttons": [
                {
                  "text": "Save",
                  "name": "allow_invalid_acl",
                  "value": "true"
                }
              ]
            }
          ]
        }
      },
      "PoolPost202": {
        "allOf": [
          {
            "$ref": "#/components/schemas/response_202"
          }
        ],
        "description": "Confirm-and-resend payload (HTTP 202) returned by `POST`/`PUT /pool`.\nTwo cases are reachable:\n\n  * A watermark or caption change requires originals to be\n    re-rendered. The task carries a `confirm` field — resend with\n    `confirm=resync` to schedule the re-sync or `confirm=skip` to\n    save without re-rendering.\n  * The post-save collection-ACL re-check exceeded its time limit\n    (default 30s, overridable via `background_invalid_acl_timelimit`).\n    The task's button carries `background_invalid_acl`=`true` — resend\n    with that parameter to finish the check in the background.\n\nSee the `confirm`, `background_invalid_acl` and\n`background_invalid_acl_timelimit` query parameters on the operation.\n",
        "example": {
          "tasks": [
            {
              "title": "Update renditions",
              "message": "2 files need to update renditions. This may be done manually in /inspect/files.",
              "form": [
                {
                  "label": "",
                  "type": "options",
                  "name": "confirm",
                  "horizontal": false,
                  "options": [
                    {
                      "text": "Update now (recommended)",
                      "value": "resync",
                      "disabled": false
                    },
                    {
                      "text": "Skip",
                      "value": "skip",
                      "disabled": false
                    }
                  ]
                }
              ],
              "buttons": [
                {
                  "text": "Save"
                }
              ]
            }
          ]
        }
      },
      "SchemaCommit202": {
        "allOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
            "required": [
              "tasks"
            ],
            "properties": {
              "tasks": {
                "type": "array",
                "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "title",
                    "message",
                    "buttons"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Short, localized heading for the confirmation."
                    },
                    "message": {
                      "type": "string",
                      "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                    },
                    "form": {
                      "type": "array",
                      "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "label",
                          "type",
                          "name",
                          "options",
                          "horizontal"
                        ],
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Localized label for the field. May be empty."
                          },
                          "type": {
                            "type": "string",
                            "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                          },
                          "options": {
                            "type": "array",
                            "description": "The selectable choices for this field.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "text",
                                "value",
                                "disabled"
                              ],
                              "properties": {
                                "text": {
                                  "type": "string",
                                  "description": "Localized label shown for this choice."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                                },
                                "disabled": {
                                  "type": "boolean",
                                  "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                                }
                              }
                            }
                          },
                          "horizontal": {
                            "type": "boolean",
                            "description": "Display hint — lay the options out in a row."
                          }
                        }
                      }
                    },
                    "buttons": {
                      "type": "array",
                      "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "Localized button label."
                          },
                          "hidden": {
                            "type": "boolean",
                            "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                          },
                          "value": {
                            "type": "string",
                            "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "description": "The `202` body of `POST /schema/commit` — a `response_202` confirm-and-resend\ntask. A change that needs a reindex shows a `reindex` options field (`skip` /\n`reindex` / `reindex_block`); a change that alters constraints shows a plain\nconfirm button with no form. Resend the call with `confirm=yes` (and, for the\nreindex case, the chosen `reindex` value) to run the commit. The example shows\nthe reindex case; the constraints case has the same shape with only the\n`buttons` entry (`name: confirm`, `value: yes`) and no `form`.\n",
        "example": {
          "tasks": [
            {
              "title": "Re-indexing",
              "message": "Your change makes a re-indexing necessary. This runs in the background and will briefly generate a higher load on the server. New records or records that have been changed in the meantime will only become visible after indexing.",
              "form": [
                {
                  "label": "",
                  "type": "options",
                  "name": "reindex",
                  "horizontal": false,
                  "options": [
                    {
                      "text": "Skip re-indexing (not recommended)",
                      "value": "skip",
                      "disabled": false
                    },
                    {
                      "text": "Perform re-indexing (recommended)",
                      "value": "reindex",
                      "disabled": false
                    },
                    {
                      "text": "Perform re-indexing and temporarily lock system",
                      "value": "reindex_block",
                      "disabled": false
                    }
                  ]
                }
              ],
              "buttons": [
                {
                  "text": "Ok",
                  "name": "confirm",
                  "value": "yes"
                }
              ]
            }
          ]
        }
      },
      "RightPresetPost202": {
        "allOf": [
          {
            "$ref": "#/components/schemas/response_202"
          }
        ],
        "description": "The `202` body of `POST /right/{context}/presets` — a `response_202`\nconfirm-and-resend task raised when, after saving the presets, re-validating\nthe affected collections' ACLs exceeds the synchronous time limit\n(`30s` by default, overridable with `background_invalid_acl_timelimit`). The\nbutton re-sends the same `POST` with `background_invalid_acl=true` (the\nbutton's `name`=`value`) to run the validity check as a background task and\nreturn immediately.\n",
        "example": {
          "tasks": [
            {
              "title": "Collection",
              "message": "Checking the collection permissions took longer than 30s and was aborted. Do you want to start this task in the background?",
              "buttons": [
                {
                  "text": "Ok",
                  "name": "background_invalid_acl",
                  "value": "true"
                }
              ]
            }
          ]
        }
      },
      "RightPresetDelete202": {
        "allOf": [
          {
            "$ref": "#/components/schemas/response_202"
          }
        ],
        "description": "The `202` body of `DELETE /right/{context}/presets/{presetId}` — a\n`response_202` confirm-and-resend task raised when the preset being deleted\nis or was in use, i.e. `right` rows reference it on current or archived\nobjects. The single button re-sends the same `DELETE` with `confirm=delete`\n(the button's `name`=`value`); only then is the preset actually deleted\ntogether with its associated permission rows in current and archived records.\n",
        "example": {
          "tasks": [
            {
              "title": "Delete preset",
              "message": "The presets to be deleted are or were in use. Deleting the presets deletes associated permission in current and archived records.",
              "buttons": [
                {
                  "text": "Delete",
                  "name": "confirm",
                  "value": "delete"
                }
              ]
            }
          ]
        }
      },
      "TagsPost202": {
        "allOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
            "required": [
              "tasks"
            ],
            "properties": {
              "tasks": {
                "type": "array",
                "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "title",
                    "message",
                    "buttons"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Short, localized heading for the confirmation."
                    },
                    "message": {
                      "type": "string",
                      "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                    },
                    "form": {
                      "type": "array",
                      "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "label",
                          "type",
                          "name",
                          "options",
                          "horizontal"
                        ],
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Localized label for the field. May be empty."
                          },
                          "type": {
                            "type": "string",
                            "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                          },
                          "options": {
                            "type": "array",
                            "description": "The selectable choices for this field.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "text",
                                "value",
                                "disabled"
                              ],
                              "properties": {
                                "text": {
                                  "type": "string",
                                  "description": "Localized label shown for this choice."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                                },
                                "disabled": {
                                  "type": "boolean",
                                  "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                                }
                              }
                            }
                          },
                          "horizontal": {
                            "type": "boolean",
                            "description": "Display hint — lay the options out in a row."
                          }
                        }
                      }
                    },
                    "buttons": {
                      "type": "array",
                      "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "Localized button label."
                          },
                          "hidden": {
                            "type": "boolean",
                            "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                          },
                          "value": {
                            "type": "string",
                            "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "description": "Confirm-and-resend payload returned by `POST /api/v1/tags` when one or more\ntags that would be deleted are still referenced only in contexts **fylr** can\nclean up automatically (`collection.create_object`, `objecttype_tag`,\n`pool_tag`). Resend the identical request with `delete_policy=remove_tags` to\nconfirm.\n",
        "example": {
          "tasks": [
            {
              "title": "Delete tags in use?",
              "message": "The tags which are to be deleted are still in use:\n\n- 1 Collection(s)\n\nShould the tags automatically be removed and deleted anyways?",
              "buttons": [
                {
                  "text": "Delete tags",
                  "name": "delete_policy",
                  "value": "remove_tags"
                }
              ]
            }
          ]
        }
      },
      "XmlMappingDelete202": {
        "allOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "description": "A confirm-and-resend payload (HTTP 202): the request was understood but needs\nthe client to confirm one or more decisions first. For each task the client\nderives the query parameter(s) it implies and re-sends the **same** request\nwith them appended. Those parameters come from the task's `form` (the chosen\noption's `value` under the field `name`) and from the button used\n(`name`=`value`); `hidden` buttons carry parameters that must be sent even\nthough they are not shown. The `name`/`value` properties below are what a\nfrontend turns into the confirmation URL.\n",
            "required": [
              "tasks"
            ],
            "properties": {
              "tasks": {
                "type": "array",
                "description": "The decisions the request raised. Every task must be resolved — its\nparameter(s) added to the re-sent request — for the request to complete.\n",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "title",
                    "message",
                    "buttons"
                  ],
                  "properties": {
                    "title": {
                      "type": "string",
                      "description": "Short, localized heading for the confirmation."
                    },
                    "message": {
                      "type": "string",
                      "description": "Localized explanation of what is being confirmed (for example that\nthe save removes the user's own access, or that the records being\ndeleted are still linked from other records).\n"
                    },
                    "form": {
                      "type": "array",
                      "description": "Optional input fields the user chooses from. The selected option's\n`value` is sent as the query parameter named by the field's `name`\nwhen the request is re-sent — this is how `delete_policy` and\n`reverse_pool_changed_mode` are chosen. Absent for a plain\nbutton-only confirmation such as revoke.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "label",
                          "type",
                          "name",
                          "options",
                          "horizontal"
                        ],
                        "properties": {
                          "label": {
                            "type": "string",
                            "description": "Localized label for the field. May be empty."
                          },
                          "type": {
                            "type": "string",
                            "description": "Input-control type of the field — `options` for a single\nchoice out of `options`.\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** under which the chosen option's\n`value` is sent when re-sending the request (for example\n`delete_policy`, `reverse_pool_changed_mode`). One of the two\nvalues a frontend reads to build the confirmation request.\n"
                          },
                          "options": {
                            "type": "array",
                            "description": "The selectable choices for this field.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "text",
                                "value",
                                "disabled"
                              ],
                              "properties": {
                                "text": {
                                  "type": "string",
                                  "description": "Localized label shown for this choice."
                                },
                                "value": {
                                  "type": "string",
                                  "description": "**Value to send** for the field's `name` parameter when\nthis choice is selected (for example `remove`,\n`setnull`, `create_collection`). The other half — with\nthe field `name` — of the confirmation parameter.\n"
                                },
                                "disabled": {
                                  "type": "boolean",
                                  "description": "When true the choice is shown but not selectable (for\nexample a delete policy that other records prevent).\n"
                                }
                              }
                            }
                          },
                          "horizontal": {
                            "type": "boolean",
                            "description": "Display hint — lay the options out in a row."
                          }
                        }
                      }
                    },
                    "buttons": {
                      "type": "array",
                      "description": "The actions offered for the task. A button whose `name` is set adds\n`name`=`value` to the re-sent request. `revoke`, `confirmTransition`\nand `revoke:confirmTransition` are the parameters the server acts on;\na generic submit button may instead carry `name: confirm`, which the\nserver ignores — there the operative parameter comes from the task's\n`form`.\n",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "Localized button label."
                          },
                          "hidden": {
                            "type": "boolean",
                            "description": "When true the button is not shown, but its `name`=`value` is a\nparameter the client must still include when re-sending — used\nto carry an already-chosen parameter across a second\nconfirmation (for example a `delete_policy` preserved while a\nworkflow transition is confirmed).\n"
                          },
                          "name": {
                            "type": "string",
                            "description": "**Query-parameter name** to add to the re-sent request when\nthis button is used (Go `ConfirmKey`). Operative names are\n`revoke`, `confirmTransition` and `revoke:confirmTransition`; a\ngeneric submit button uses `confirm`, which the server ignores.\n"
                          },
                          "value": {
                            "type": "string",
                            "description": "**Value** for the `name` parameter (Go `ConfirmValue`) — for\nexample `yes` for `revoke`, or the confirmation token for\n`confirmTransition`.\n"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "description": "Returned by `DELETE /xmlmapping/mapping/{mapping}` when the mapping is\nstill linked from one or more collections' upload settings\n(`collection_create_object.mapping_id`). Re-send the same `DELETE` with\n`?delete_policy=delete` to unlink it from every affected collection\n(sets `mapping_id` to `NULL`) and then delete the mapping.\n",
        "example": {
          "tasks": [
            {
              "title": "Confirmation",
              "message": "The Metadata Mapping you are about to delete is linked in the upload settings of the following 2 collections:\n\n- My Imports\n- Archive\n\nShould the mapping be removed from the collection settings and be deleted?",
              "form": [
                {
                  "label": "",
                  "type": "options",
                  "name": "delete_policy",
                  "horizontal": false,
                  "options": [
                    {
                      "text": "Unlink from collections and delete mapping",
                      "value": "delete",
                      "disabled": false
                    }
                  ]
                }
              ],
              "buttons": [
                {
                  "text": "Confirm",
                  "name": "confirm",
                  "value": "delete"
                }
              ]
            }
          ]
        }
      },
      "Error": {
        "type": "object",
        "description": "Standard error envelope. Every **fylr** API error is returned as a JSON object\nin this shape, together with the matching HTTP status code.\n",
        "required": [
          "code",
          "error"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code, for example `UnknownObjecttype` or\n`VersionMismatch`. Use this to branch on errors in client code instead of\nparsing the `error` message.\n"
          },
          "error": {
            "type": "string",
            "description": "Human-readable error message. Intended for developers and log output, not\nfor display to end users.\n"
          },
          "package": {
            "type": "string",
            "description": "Internal origin marker for the error, for **fylr** support and logs. It is\nnot part of the API contract and carries no meaning for clients — branch on\n`code`, never on `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Additional, error-specific details. Which keys are present depends on the\n`code`. An empty object when the error carries no extra information.\n"
          },
          "realm": {
            "type": "string",
            "description": "Realm the error originates from. For API errors this is `api`.\n"
          },
          "description": {
            "type": "string",
            "description": "Optional longer explanation of the error.\n"
          },
          "statuscode": {
            "type": "integer",
            "description": "The HTTP status code, repeated here for convenience.\n"
          }
        }
      },
      "EventTypeNotAllowedError": {
        "type": "object",
        "description": "Error returned with `code` `EventTypeNotAllowed` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `EventTypeNotAllowed` — the `type` in the payload is not one of\n    the user-event types that may be written through the API (i.e. it\n    is unknown to the server, or it is not a FRONTEND/PLUGIN type and\n    `skip_constraints` was not set by a root caller).\n    `parameters.type` carries the offending value.\n",
            "enum": [
              "EventTypeNotAllowed"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "userevent"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `type`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "EventTypeNotAllowed",
          "error": "The event type OBJECT_INSERT is not allowed.",
          "package": "userevent",
          "parameters": {
            "type": "OBJECT_INSERT",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "EasInvalidURLError": {
        "type": "object",
        "description": "Error returned with `code` `EasInvalidURL` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `EasInvalidURL` — see the referencing response description.\n",
            "enum": [
              "EasInvalidURL"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `url`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "EventNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `EventNotFound` (HTTP `404`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `EventNotFound` — see the referencing response description.\n",
            "enum": [
              "EventNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `event`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              404
            ],
            "description": "The HTTP status code, repeated here. Always `404`."
          }
        }
      },
      "MessageNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `MessageNotFound` (HTTP `404`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `MessageNotFound` — see the referencing response description.\n",
            "enum": [
              "MessageNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "message"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `id`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              404
            ],
            "description": "The HTTP status code, repeated here. Always `404`."
          }
        }
      },
      "ObjecttypeNeedsStandardMaskError": {
        "type": "object",
        "description": "Error returned with `code` `ObjecttypeNeedsStandardMask` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ObjecttypeNeedsStandardMask` — see the referencing response description.\n",
            "enum": [
              "ObjecttypeNeedsStandardMask"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UnknownEndpointMethodError": {
        "type": "object",
        "description": "Error returned with `code` `UnknownEndpointMethod` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnknownEndpointMethod` — see the referencing response description.\n",
            "enum": [
              "UnknownEndpointMethod"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `endpoint`, `method`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UrlParameterNotSupportedError": {
        "type": "object",
        "description": "Error returned with `code` `UrlParameterNotSupported` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UrlParameterNotSupported` — see the referencing response description.\n",
            "enum": [
              "UrlParameterNotSupported"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `param`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ApiObjectPathError": {
        "type": "object",
        "description": "Error returned with `code` `ApiObjectPath` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ApiObjectPath` — an invalid api-object path was requested inside an\n    export archive. Other 400 codes from the server pipeline may also\n    surface here. Most of these codes are `400`; `ExportDuplicateName`\n    is `409` and `FileNotFound` is `404` — see `statuscode`.\n",
            "enum": [
              "ApiObjectPath"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `path`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "BackupNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `BackupNotFound` (HTTP `404`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `BackupNotFound` — no backup with the addressed id is on file.\n    `parameters.backupid` carries the id that was looked up.\n",
            "enum": [
              "BackupNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "backup"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `backupid`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              404
            ],
            "description": "The HTTP status code, repeated here. Always `404`."
          }
        },
        "example": {
          "code": "BackupNotFound",
          "error": "Backup #89 was not found.",
          "package": "backup",
          "parameters": {
            "backupid": 89,
            "realm": "api",
            "statuscode": 404
          },
          "realm": "api",
          "statuscode": 404
        }
      },
      "ChoiceNotUniqueError": {
        "type": "object",
        "description": "Error returned with `code` `ChoiceNotUnique` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ChoiceNotUnique` — the preset enables more than one option of a\n    `choice` right; only one may be set. `parameters.choice` identifies\n    the choice group. Generic 400 codes from the server pipeline\n    (request parsing, `ReadOnlyMode`, ...) may also surface here.\n",
            "enum": [
              "ChoiceNotUnique"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "rightcheck"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `choice`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "CollectionObjectInsufficientRightsError": {
        "type": "object",
        "description": "Error returned with `code` `CollectionObjectInsufficientRights` (HTTP\n`403`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `CollectionObjectInsufficientRights` — only on writes that share\n    rights: the collection's `_owner` lacks a grantable right for one of\n    the linked objects, so the collection's ACL cannot be applied.\n    `parameters` carries `systemobjectid`, `displayname`, `owner`,\n    `right` and `rightdisplayname`.\n",
            "enum": [
              "CollectionObjectInsufficientRights"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `displayname`, `owner`, `right`,\n`rightdisplayname`, `systemobjectid`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              403
            ],
            "description": "The HTTP status code, repeated here. Always `403`."
          }
        }
      },
      "CollectionRemoveNotAllObjectsFoundError": {
        "type": "object",
        "description": "Error returned with `code` `CollectionRemoveNotAllObjectsFound` (HTTP\n`400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `CollectionRemoveNotAllObjectsFound` — `POST\n    /api/v1/collection/remove/{id}` referenced one or more objects that\n    are not currently linked to the collection. The raise site sets no\n    parameters, so `parameters` is empty for this code; the human-\n    readable `error` is the constant \"The collection does not contain\n    all objects requested to remove\". Other 400 codes from the server\n    pipeline (request parsing, `ReadOnlyMode`, `LookupNotFound`,\n    `LookupFoundTooMany`, …) may also surface here.\n",
            "enum": [
              "CollectionRemoveNotAllObjectsFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "objects"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `field`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "CollectionRemoveNotAllObjectsFound",
          "error": "The collection does not contain all records requested to remove.",
          "package": "objects",
          "parameters": {
            "field": "",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "ColumnCanNotBeUpdatedError": {
        "type": "object",
        "description": "Error returned with `code` `ColumnCanNotBeUpdated` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ColumnCanNotBeUpdated` — a property is set-once and cannot be\n    changed after the user is created.\n",
            "enum": [
              "ColumnCanNotBeUpdated"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `column`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ColumnNeedsSystemRootError": {
        "type": "object",
        "description": "Error returned with `code` `ColumnNeedsSystemRoot` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ColumnNeedsSystemRoot` — a property in the payload may only be set\n    by a user holding `system.root`.\n",
            "enum": [
              "ColumnNeedsSystemRoot"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `column`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "CustomMetadataRecipeNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `CustomMetadataRecipeNotFound` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `CustomMetadataRecipeNotFound` — a metadata extraction recipe\n    referenced from the upload payload is not present in any active\n    config (often a side-effect of an unsupported file extension).\n    `parameters.recipe` carries the recipe name. Other 400 codes from\n    the server pipeline (request parsing, SSRF block on the upstream URL\n    for /eas/rput, `ReadOnlyMode`, ...) may also surface here.\n",
            "enum": [
              "CustomMetadataRecipeNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "filesync"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `recipe`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "DatabaseLockError": {
        "type": "object",
        "description": "Error returned with `code` `DatabaseLockError` (HTTP `423`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `DatabaseLockError` — unable to acquire a database lock; another\n    write is in progress on the same object.\n",
            "enum": [
              "DatabaseLockError"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `object`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              423
            ],
            "description": "The HTTP status code, repeated here. Always `423`."
          }
        },
        "example": {
          "code": "DatabaseLockError",
          "error": "Unable to acquire a lock for resource \"\".",
          "package": "ferrors",
          "parameters": {
            "object": "",
            "realm": "api",
            "statuscode": 423
          },
          "realm": "api",
          "statuscode": 423
        }
      },
      "DatabaseUniqueKeyViolationError": {
        "type": "object",
        "description": "Error returned with `code` `DatabaseUniqueKeyViolation` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `DatabaseUniqueKeyViolation` — a uniqueness constraint was violated\n    (for example, a duplicate reference value).\n",
            "enum": [
              "DatabaseUniqueKeyViolation"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "DatamodelVersionNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `DatamodelVersionNotFound` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `DatamodelVersionNotFound` — the requested datamodel version does\n    not exist (for example `GET /schema/user/{version}` with an unknown\n    or non-positive version).\n",
            "enum": [
              "DatamodelVersionNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `version`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "DatamodelVersionNotFound",
          "error": "Data model with version \"HENK\" was not found.",
          "package": "datamodel",
          "parameters": {
            "version": "HENK",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "DateWrongSyntaxError": {
        "type": "object",
        "description": "Error returned with `code` `DateWrongSyntax` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `DateWrongSyntax` — a date value in the query has the wrong syntax.\n",
            "enum": [
              "DateWrongSyntax"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "search"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `date`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "DeepLinkAccessByColumnDisabledError": {
        "type": "object",
        "description": "Error returned with `code` `DeepLinkAccessByColumnDisabled` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `DeepLinkAccessByColumnDisabled` — a `column/...` selector was used\n    while `system.deep_link_access.allow_access_by_column` is off.\n",
            "enum": [
              "DeepLinkAccessByColumnDisabled"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "DeepLinkAccessByIdDisabledError": {
        "type": "object",
        "description": "Error returned with `code` `DeepLinkAccessByIdDisabled` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `DeepLinkAccessByIdDisabled` — an `id/\u003csystem-object-id\u003e` selector\n    was used while `system.deep_link_access.allow_access_by_id` is off.\n",
            "enum": [
              "DeepLinkAccessByIdDisabled"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "DeepLinkAccessDisabledError": {
        "type": "object",
        "description": "Error returned with `code` `DeepLinkAccessDisabled` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `DeepLinkAccessDisabled` — deep-link access is turned off in the\n    base config (`system.deep_link_access.enabled = false`). Returned\n    before any path parsing.\n",
            "enum": [
              "DeepLinkAccessDisabled"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "DeepLinkAccessDisabled",
          "error": "The deep link access needs to be enabled in the base configuration.",
          "package": "api",
          "parameters": {
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "DeleteSystemGroupError": {
        "type": "object",
        "description": "Error returned with `code` `DeleteSystemGroup` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `DeleteSystemGroup` — attempt to delete a group whose `type` is\n    `system`. System groups cannot be deleted.\n",
            "enum": [
              "DeleteSystemGroup"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "DeleteSystemUserError": {
        "type": "object",
        "description": "Error returned with `code` `DeleteSystemUser` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `DeleteSystemUser` — attempt to delete a system user (`system:root`,\n    …). System users are immutable.\n",
            "enum": [
              "DeleteSystemUser"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "EasEmptyFilenameError": {
        "type": "object",
        "description": "Error returned with `code` `EasEmptyFilename` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `EasEmptyFilename` — `POST /eas/rput` received an empty filename.\n",
            "enum": [
              "EasEmptyFilename"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "filesync"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "EasInvalidFilenameError": {
        "type": "object",
        "description": "Error returned with `code` `EasInvalidFilename` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `EasInvalidFilename` — `POST /eas/rput` received a filename that\n    fails validation. `parameters.filename` carries the offending input.\n",
            "enum": [
              "EasInvalidFilename"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "filesync"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `filename`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "EasNoParentIDError": {
        "type": "object",
        "description": "Error returned with `code` `EasNoParentID` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `EasNoParentID` — `POST /eas/put` (when creating a new version)\n    received a request without a `parent_id` reference.\n",
            "enum": [
              "EasNoParentID"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "fileupload"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "EasRputError": {
        "type": "object",
        "description": "Error returned with `code` `EasRputError` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `EasRputError` — `POST /eas/rput` could not fetch the remote\n    resource. `parameters.url` and `parameters.msg` carry the upstream\n    target and underlying error.\n",
            "enum": [
              "EasRputError"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "filesync"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `msg`, `url`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "EasRputErrorContentLengthError": {
        "type": "object",
        "description": "Error returned with `code` `EasRputErrorContentLength` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `EasRputErrorContentLength` — `POST /eas/rput` got no usable\n    `Content-Length` from the remote. `parameters.url` and\n    `parameters.content_length` carry the upstream target and the\n    (invalid) length.\n",
            "enum": [
              "EasRputErrorContentLength"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "filesync"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `contentlength`, `url`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "EmailSentError": {
        "type": "object",
        "description": "Error returned with `code` `EmailSent` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `EmailSent` — sending the message failed (template render failure,\n    MTA rejection, recipient validation, attachment fetch).\n    `parameters.msg` carries the underlying message.\n",
            "enum": [
              "EmailSent"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "email"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `msg`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "EmailSent",
          "error": "Sending email failed: dial tcp smtp.example.com:25: connect: connection refused.",
          "package": "email",
          "parameters": {
            "msg": "dial tcp smtp.example.com:25: connect: connection refused",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "ExportDuplicateNameError": {
        "type": "object",
        "description": "Error returned with `code` `ExportDuplicateName` (HTTP `409`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ExportDuplicateName` — another export owned by the same user\n    already uses the requested `name` (statuscode `409`).\n    `parameters.name` carries the conflicting value.\n",
            "enum": [
              "ExportDuplicateName"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              409
            ],
            "description": "The HTTP status code, repeated here. Always `409`."
          }
        },
        "example": {
          "code": "ExportDuplicateName",
          "error": "Export name \"weekly-press-kit\" already exists.",
          "package": "export",
          "parameters": {
            "name": "weekly-press-kit",
            "realm": "api",
            "statuscode": 409
          },
          "realm": "api",
          "statuscode": 409
        }
      },
      "FileGroupNotAvailableError": {
        "type": "object",
        "description": "Error returned with `code` `FileGroupNotAvailable` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `FileGroupNotAvailable` — the export run's grouping structure no\n    longer matches the requested path inside the archive.\n",
            "enum": [
              "FileGroupNotAvailable"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `available`, `group`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "FileLimitExceededError": {
        "type": "object",
        "description": "Error returned with `code` `FileLimitExceeded` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `FileLimitExceeded` — the upload exceeds\n    `fylr.eas.upload.max_filesize`. `parameters.filesize` and\n    `parameters.limit` carry the offending and allowed sizes.\n",
            "enum": [
              "FileLimitExceeded"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "fileupload"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `filesize`, `limit`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "FileLimitExceeded",
          "error": "Allowed file size 100.0 MB exceeded.",
          "package": "fileupload",
          "parameters": {
            "filesize": "210.0 MB",
            "limit": "100.0 MB",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "FileNotDoneError": {
        "type": "object",
        "description": "Error returned with `code` `FileNotDone` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `FileNotDone` — the download was attempted while the file being\n    exported is not yet in status `done`. `parameters.file` and\n    `parameters.status` describe it.\n",
            "enum": [
              "FileNotDone"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `file`, `status`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "FileNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `FileNotFound` (HTTP `404`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `FileNotFound` — a download path addressed a file that does not\n    exist in the export (statuscode `404`). `parameters.file` carries\n    the requested path.\n",
            "enum": [
              "FileNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `file`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              404
            ],
            "description": "The HTTP status code, repeated here. Always `404`."
          }
        }
      },
      "FileVersionNotAvailableError": {
        "type": "object",
        "description": "Error returned with `code` `FileVersionNotAvailable` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `FileVersionNotAvailable` — the requested `file_version/name/\u003cname\u003e`\n    is not among the file's available versions.\n",
            "enum": [
              "FileVersionNotAvailable"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `available`, `version`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "GroupTypeChangeNotAllowedError": {
        "type": "object",
        "description": "Error returned with `code` `GroupTypeChangeNotAllowed` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `GroupTypeChangeNotAllowed` — the group `type` cannot be changed\n    after the group exists. Other 400 codes from the server pipeline may\n    also surface here, for example `ReadOnlyMode` (the instance is in\n    read-only mode) and `VersionMismatch` (on update, the supplied\n    `group._version` does not equal the stored version + 1).\n",
            "enum": [
              "GroupTypeChangeNotAllowed"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "GroupTypeNotAllowedError": {
        "type": "object",
        "description": "Error returned with `code` `GroupTypeNotAllowed` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `GroupTypeNotAllowed` — the requested group `type` is not allowed on\n    create. In practice this is raised for `type: system`;\n    `parameters.type` carries the offending value.\n",
            "enum": [
              "GroupTypeNotAllowed"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `type`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "GroupTypeNotAllowed",
          "error": "The group type \"system\" is not allowed.",
          "package": "acl",
          "parameters": {
            "type": "system",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "IllegalPathForPoolError": {
        "type": "object",
        "description": "Error returned with `code` `IllegalPathForPool` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `IllegalPathForPool` — the requested parent placement would make a\n    pool its own parent/descendant. Raised on POST/PUT. `parameters.id`\n    is the offending pool id.\n",
            "enum": [
              "IllegalPathForPool"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "pool"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `id`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "IllegalPathForPool",
          "error": "The pool #42 contains itself as parent and cannot be saved.",
          "package": "pool",
          "parameters": {
            "id": 42,
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "InheritanceNotSupportedError": {
        "type": "object",
        "description": "Error returned with `code` `InheritanceNotSupported` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `InheritanceNotSupported` — a mask attempts to inherit from another\n    mask in a way the datamodel does not allow (cross-objecttype\n    inheritance, cyclic inheritance, ...).\n",
            "enum": [
              "InheritanceNotSupported"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `field`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "InsufficientRightsError": {
        "type": "object",
        "description": "Error returned with `code` `InsufficientRights` (HTTP `403`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `InsufficientRights` — the caller may not access the addressed\n    resource. `parameters.resource` names the rejected target — on the\n    eas endpoints `\u003cfile_id\u003e/\u003chash\u003e/\u003cversion\u003e` when `hash` or `version`\n    do not match, `\u003cfile_id\u003e/signature wrong` or `\u003cfile_id\u003e/signature\n    expired` for a bad `x-fylr-signature`, and `File` when the caller\n    holds no right on the file; on task endpoints `parameters.task_id`\n    names the task instead.\n",
            "enum": [
              "InsufficientRights"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`. This code is raised from:\n`api`, `rightcheck`, `task`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `resource`, `taskid`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              403
            ],
            "description": "The HTTP status code, repeated here. Always `403`."
          }
        },
        "example": {
          "code": "InsufficientRights",
          "error": "Insufficient rights to access resource 42/9f8b1c2d/original.jpg.",
          "package": "api",
          "parameters": {
            "realm": "api",
            "resource": "42/9f8b1c2d/original.jpg",
            "statuscode": 403
          },
          "realm": "api",
          "statuscode": 403
        }
      },
      "InvalidIdentifierError": {
        "type": "object",
        "description": "Error returned with `code` `InvalidIdentifier` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `InvalidIdentifier` — an objecttype / mask / column name does not\n    match the identifier regex (`^[a-z][a-z0-9\\-_]{0,128}[a-z0-9]$`).\n",
            "enum": [
              "InvalidIdentifier"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `identifier`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "InvalidMaskModeError": {
        "type": "object",
        "description": "Error returned with `code` `InvalidMaskMode` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `InvalidMaskMode` — a mask declares an unknown `mode` value.\n",
            "enum": [
              "InvalidMaskMode"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `allowed`, `field`, `mode`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "LinkMaskNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `LinkMaskNotFound` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `LinkMaskNotFound` — a link column references a mask that does not\n    exist on the linked objecttype.\n",
            "enum": [
              "LinkMaskNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `field`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "LookupFoundTooManyError": {
        "type": "object",
        "description": "Error returned with `code` `LookupFoundTooMany` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `LookupFoundTooMany` — a lookup in the payload matched more than one\n    object; lookups must resolve to exactly one.\n",
            "enum": [
              "LookupFoundTooMany"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `count`, `value`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "LookupNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `LookupNotFound` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `LookupNotFound` — a lookup used to identify an object matched\n    nothing. Other delete-validation errors may also surface here.\n",
            "enum": [
              "LookupNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `key`, `value`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ModuleUnknownError": {
        "type": "object",
        "description": "Error returned with `code` `ModuleUnknown` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ModuleUnknown` — the `task_module` named in the payload is not\n    registered on this fylr instance. `parameters.name` carries the\n    offending module name.\n",
            "enum": [
              "ModuleUnknown"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "task"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "ModuleUnknown",
          "error": "The module name \"indexing\" is unknown.",
          "package": "task",
          "parameters": {
            "name": "indexing",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "NestedQueryInError": {
        "type": "object",
        "description": "Error returned with `code` `NestedQueryIn` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `NestedQueryIn` — an `in` query targets an entire nested object,\n    which is not supported.\n",
            "enum": [
              "NestedQueryIn"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "search"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "NoMasksForCreateError": {
        "type": "object",
        "description": "Error returned with `code` `NoMasksForCreate` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `NoMasksForCreate` — the requested `objecttype` (and `pool_id`, if\n    given) has no mask the user could create new objects against.\n    `parameters.objecttype` and `parameters.pool` carry the input.\n",
            "enum": [
              "NoMasksForCreate"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "dbinfo"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `objecttype`, `pool`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "NoPasswordError": {
        "type": "object",
        "description": "Error returned with `code` `NoPassword` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `NoPassword` — `/user/change_password` was called without providing\n    the new password.\n",
            "enum": [
              "NoPassword"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "OAIpmhNotEnabledError": {
        "type": "object",
        "description": "Error returned with `code` `OAIpmhNotEnabled` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `OAIpmhNotEnabled` — the instance has the OAI-PMH endpoint turned\n    off in its base config (`fylr.oai_pmh.enabled = false`).\n",
            "enum": [
              "OAIpmhNotEnabled"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "OAIpmhNotEnabled",
          "error": "The OAI/PMH endpoint is not enabled.",
          "package": "api",
          "parameters": {
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "ObjectInsufficientAssetDownloadRightError": {
        "type": "object",
        "description": "Error returned with `code` `ObjectInsufficientAssetDownloadRight` (HTTP\n`403`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ObjectInsufficientAssetDownloadRight` — the operation failed with\n    this code.\n",
            "enum": [
              "ObjectInsufficientAssetDownloadRight"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `fileid`, `rightdisplayname`,\n`systemobjectid`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              403
            ],
            "description": "The HTTP status code, repeated here. Always `403`."
          }
        }
      },
      "ObjectInsufficientRightsError": {
        "type": "object",
        "description": "Error returned with `code` `ObjectInsufficientRights` (HTTP `403`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ObjectInsufficientRights` — the user lacks a required permission on\n    a specific object (for example `read`, `write`, `delete`).\n",
            "enum": [
              "ObjectInsufficientRights"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `objecttype`, `right`, `rightdisplayname`,\n`systemobjectid`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              403
            ],
            "description": "The HTTP status code, repeated here. Always `403`."
          }
        },
        "example": {
          "code": "ObjectInsufficientRights",
          "error": "The operation could not be performed because you do not have the “Write” (write) right for the record #4711 [picture].",
          "package": "ferrors",
          "parameters": {
            "objecttype": "picture",
            "systemobjectid": 4711,
            "right": "write",
            "rightdisplayname": "Write",
            "realm": "api",
            "statuscode": 403
          },
          "realm": "api",
          "statuscode": 403
        }
      },
      "ObjectNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `ObjectNotFound` (HTTP `404`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ObjectNotFound` — the entity addressed by the URL was not found.\n    `parameters.object` carries an `\u003carea\u003e:\u003cid\u003e` token so the caller can\n    correlate (for example `collection:42`, `task:7`).\n",
            "enum": [
              "ObjectNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `object`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              404
            ],
            "description": "The HTTP status code, repeated here. Always `404`."
          }
        },
        "example": {
          "code": "ObjectNotFound",
          "error": "Record collection:42 was not found.",
          "package": "ferrors",
          "parameters": {
            "object": "collection:42",
            "realm": "api",
            "statuscode": 404
          },
          "realm": "api",
          "statuscode": 404
        }
      },
      "ObjecttypeMustHaveExtactlyOnePreferredMaskError": {
        "type": "object",
        "description": "Error returned with `code` `ObjecttypeMustHaveExtactlyOnePreferredMask`\n(HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ObjecttypeMustHaveExtactlyOnePreferredMask` — exactly one mask per\n    objecttype must have `is_preferred: true`. (The wire spelling has\n    the historical `Extactly` typo.)\n",
            "enum": [
              "ObjecttypeMustHaveExtactlyOnePreferredMask"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `objecttype`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ObjecttypeNotEmptyError": {
        "type": "object",
        "description": "Error returned with `code` `ObjecttypeNotEmpty` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ObjecttypeNotEmpty` — a commit / HEAD write would delete an\n    objecttype that still holds objects; `parameters` names the affected\n    objecttypes. Other 400 codes from the server pipeline (request\n    parsing, `ReadOnlyMode`, ...) may also surface here, and `package`\n    is not always `datamodel` (for example `ObjecttypeNotEmpty` is\n    package `api`, `ReadOnlyMode` is `ferrors`).\n",
            "enum": [
              "ObjecttypeNotEmpty"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `stats`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ObjecttypeNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `ObjecttypeNotFound` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ObjecttypeNotFound` — the `objecttype` in the request body is not\n    defined in the current datamodel. `parameters.objecttype` carries\n    the name.\n",
            "enum": [
              "ObjecttypeNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "dbinfo"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `objecttype`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "ObjecttypeNotFound",
          "error": "Object type pictures not found.",
          "package": "dbinfo",
          "parameters": {
            "objecttype": "pictures",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "PasswordChangedRequiredError": {
        "type": "object",
        "description": "Error returned with `code` `PasswordChangedRequired` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PasswordChangedRequired` — the user must change their password\n    before they can perform the requested operation.\n",
            "enum": [
              "PasswordChangedRequired"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "PluginDisabledError": {
        "type": "object",
        "description": "Error returned with `code` `PluginDisabled` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PluginDisabled` — the plugin exists but is not enabled, so its\n    static assets and extension routes are not served (HTTP 400).\n",
            "enum": [
              "PluginDisabled"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `plugin`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "PluginDisabled",
          "error": "Plugin fylr_example is disabled.",
          "package": "api",
          "parameters": {
            "plugin": "fylr_example",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "PluginDuplicateNameError": {
        "type": "object",
        "description": "Error returned with `code` `PluginDuplicateName` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PluginDuplicateName` — a `PUT /plugin/manage` tried to create a\n    plugin whose `name` is already taken (HTTP 400).\n",
            "enum": [
              "PluginDuplicateName"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `plugin`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "PluginNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `PluginNotFound` (HTTP `404`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PluginNotFound` — no plugin with the requested name or id exists\n    (HTTP 404).\n",
            "enum": [
              "PluginNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `plugin`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              404
            ],
            "description": "The HTTP status code, repeated here. Always `404`."
          }
        }
      },
      "PoolNeedsParentError": {
        "type": "object",
        "description": "Error returned with `code` `PoolNeedsParent` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PoolNeedsParent` — a non-root pool was saved without a parent;\n    pools cannot be saved at the top-level root. Other 400 codes from\n    the server pipeline may also surface here.\n",
            "enum": [
              "PoolNeedsParent"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "rightcheck"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "PoolNotEmptyError": {
        "type": "object",
        "description": "Error returned with `code` `PoolNotEmpty` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PoolNotEmpty` — DELETE was attempted on a pool that still contains\n    objects (directly or via sub-pools). `parameters.stats` lists the\n    non-empty objecttypes.\n",
            "enum": [
              "PoolNotEmpty"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `stats`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ProduceExtensionNotSupportedError": {
        "type": "object",
        "description": "Error returned with `code` `ProduceExtensionNotSupported` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ProduceExtensionNotSupported` — the source file extension is not\n    one /eas/produce can read. `parameters.extension` and\n    `parameters.supported_extensions` carry the input and the allow-\n    list.\n",
            "enum": [
              "ProduceExtensionNotSupported"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "fileupload"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `extension`, `supportedextensions`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ProduceFormatNotSupportedError": {
        "type": "object",
        "description": "Error returned with `code` `ProduceFormatNotSupported` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ProduceFormatNotSupported` — the requested output format is not one\n    /eas/produce can write. `parameters.format` and\n    `parameters.supported_formats` carry the input and the allow-list.\n",
            "enum": [
              "ProduceFormatNotSupported"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "fileupload"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `format`, `supportedformats`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ProduceOriginalOnlyError": {
        "type": "object",
        "description": "Error returned with `code` `ProduceOriginalOnly` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ProduceOriginalOnly` — `POST /eas/produce` was called against a\n    non-original version. Only originals can be rotated or cropped.\n",
            "enum": [
              "ProduceOriginalOnly"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "fileupload"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "PublishDeletedObjectError": {
        "type": "object",
        "description": "Error returned with `code` `PublishDeletedObject` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PublishDeletedObject` — the targeted object has been (soft-)deleted\n    and cannot receive a new publication. `parameters.object` is the\n    `#\u003csystem_object_id\u003e` token. Message: `Unable to publish deleted\n    object \"\u003cobject\u003e\".` A read-only instance is rejected before any of\n    these checks with `ReadOnlyMode` (`package: ferrors`), returned as\n    the standard `Error` envelope, not with a publish-specific `code`.\n",
            "enum": [
              "PublishDeletedObject"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "object"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `object`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "PublishInvalidDataError": {
        "type": "object",
        "description": "Error returned with `code` `PublishInvalidData` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PublishInvalidData` — `publish_uri` or `easydb_uri` is missing or\n    blank (the value is whitespace-trimmed and must be non-empty).\n    `parameters.field` is `publish_uri` or `easydb_uri`;\n    `parameters.value` is the empty string. Message: `The value \"\" of\n    field \"\u003cfield\u003e\" is invalid.`\n",
            "enum": [
              "PublishInvalidData"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "object"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `field`, `value`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "PublishUnknownCollectorError": {
        "type": "object",
        "description": "Error returned with `code` `PublishUnknownCollector` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PublishUnknownCollector` — the `collector` named in the payload is\n    not configured in this instance (checked first). The base config\n    registers the collectors that are valid here. `parameters.collector`\n    carries the offending value. Message: `The collector \"\u003cname\u003e\"\n    unknown and cannot be used. It must be configured in the base\n    config.`\n",
            "enum": [
              "PublishUnknownCollector"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "object"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `collector`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "PublishUnknownCollector",
          "error": "The collector \"datacite\" is unknown and cannot be used. It must be configured in the base config.",
          "package": "object",
          "parameters": {
            "collector": "datacite",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "PurgeSystemRootOnlyError": {
        "type": "object",
        "description": "Error returned with `code` `PurgeSystemRootOnly` (HTTP `403`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `PurgeSystemRootOnly` — the user holds `system.root` but is not the\n    `system:root` user; only that user may purge.\n",
            "enum": [
              "PurgeSystemRootOnly"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              403
            ],
            "description": "The HTTP status code, repeated here. Always `403`."
          }
        },
        "example": {
          "code": "PurgeSystemRootOnly",
          "error": "Only the system user with reference 'system:root' is allowed to purge.",
          "package": "acl",
          "parameters": {
            "realm": "api",
            "statuscode": 403
          },
          "realm": "api",
          "statuscode": 403
        }
      },
      "QueryParseError": {
        "type": "object",
        "description": "Error returned with `code` `QueryParse` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `QueryParse` — the query string is not syntactically valid.\n",
            "enum": [
              "QueryParse"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "query"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `msg`, `query`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "QueryParse",
          "error": "title ==: 1:9: error: expected one of \"?\", null, string, int, uint, or \"[\"; got: end-of-file.",
          "package": "query",
          "parameters": {
            "query": "title ==",
            "msg": "1:9: error: expected one of \"?\", null, string, int, uint, or \"[\"; got: end-of-file",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "ReadOnlyModeError": {
        "type": "object",
        "description": "Error returned with `code` `ReadOnlyMode` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ReadOnlyMode` — the instance is in read-only mode and rejects\n    writes.\n",
            "enum": [
              "ReadOnlyMode"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "ReadOnlyMode",
          "error": "Read-only mode is enabled.",
          "package": "ferrors",
          "parameters": {
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "RecipeParamUnsupportedValueError": {
        "type": "object",
        "description": "Error returned with `code` `RecipeParamUnsupportedValue` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `RecipeParamUnsupportedValue` — a produce recipe parameter\n    received a value that is not among the recipe's options (for\n    example an unknown `colorprofile` or `colorspace` in\n    `POST /eas/produce`). `parameters` carries the parameter name\n    (`Param`), its type (`Type`) and the rejected value (`Value`).\n",
            "enum": [
              "RecipeParamUnsupportedValue"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "baseconfig"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ReindexInProgressError": {
        "type": "object",
        "description": "Error returned with `code` `ReindexInProgress` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ReindexInProgress` — a reindex is already running and the request\n    conflicts with it.\n",
            "enum": [
              "ReindexInProgress"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "search"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ResourceNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `ResourceNotFound` (HTTP `404`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ResourceNotFound` — the addressed resource (typically a file id)\n    does not exist. `parameters.resource` carries an identifier for the\n    missing target, e.g. `file \u003cfile_id\u003e`.\n",
            "enum": [
              "ResourceNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`. This code is raised from:\n`api`, `filedownload`, `save`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `resource`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              404
            ],
            "description": "The HTTP status code, repeated here. Always `404`."
          }
        },
        "example": {
          "code": "ResourceNotFound",
          "error": "Resource file 42 not found.",
          "package": "api",
          "parameters": {
            "resource": "file 42",
            "realm": "api",
            "statuscode": 404
          },
          "realm": "api",
          "statuscode": 404
        }
      },
      "RightRequiredError": {
        "type": "object",
        "description": "Error returned with `code` `RightRequired` (HTTP `403`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `RightRequired` — the caller can use the endpoint but lacks one\n    specific right, e.g. `asset_upload` when uploading or producing\n    files. `parameters.right` names it, `parameters.rightdisplayname`\n    carries its localized label.\n",
            "enum": [
              "RightRequired"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "rightcheck"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `right`, `rightdisplayname`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              403
            ],
            "description": "The HTTP status code, repeated here. Always `403`."
          }
        },
        "example": {
          "code": "RightRequired",
          "error": "Current user is missing permission \"bag_write\" (\"View \u0026 Edit Collection\").",
          "package": "rightcheck",
          "parameters": {
            "right": "bag_write",
            "rightdisplayname": "View \u0026 Edit Collection",
            "realm": "api",
            "statuscode": 403
          },
          "realm": "api",
          "statuscode": 403
        }
      },
      "SchemaDuplicateMaskNameError": {
        "type": "object",
        "description": "Error returned with `code` `SchemaDuplicateMaskName` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `SchemaDuplicateMaskName` — two masks on the same objecttype share a\n    name.\n",
            "enum": [
              "SchemaDuplicateMaskName"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "SchemaDuplicateObjecttypeNameError": {
        "type": "object",
        "description": "Error returned with `code` `SchemaDuplicateObjecttypeName` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `SchemaDuplicateObjecttypeName` — two objecttypes share a name.\n",
            "enum": [
              "SchemaDuplicateObjecttypeName"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "SchemaDuplicateObjecttypeName",
          "error": "Objecttype name \"picture\" must be unique.",
          "package": "datamodel",
          "parameters": {
            "name": "picture",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "SchemaInconsistentError": {
        "type": "object",
        "description": "Error returned with `code` `SchemaInconsistent` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `SchemaInconsistent` — the payload does not match the object type's\n    schema (unexpected field, wrong type, …). Other validation errors\n    from the save pipeline may also surface here.\n",
            "enum": [
              "SchemaInconsistent"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `msg`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "SchemaLoopingReverseError": {
        "type": "object",
        "description": "Error returned with `code` `SchemaLoopingReverse` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `SchemaLoopingReverse` — a reverse-link column closes a loop the\n    indexer cannot resolve.\n",
            "enum": [
              "SchemaLoopingReverse"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `table1`, `table2`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "SearchFieldNotAllowedError": {
        "type": "object",
        "description": "Error returned with `code` `SearchFieldNotAllowed` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `SearchFieldNotAllowed` — a `search` element uses a field that is\n    not allowed in the current search context.\n",
            "enum": [
              "SearchFieldNotAllowed"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "search"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `context`, `field`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "SearchFieldUnknownError": {
        "type": "object",
        "description": "Error returned with `code` `SearchFieldUnknown` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `SearchFieldUnknown` — a `search` element references a field that\n    does not exist.\n",
            "enum": [
              "SearchFieldUnknown"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "search"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `context`, `field`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "SearchFieldUnknown",
          "error": "The search field \"nonexistent_field\" is unknown.",
          "package": "search",
          "parameters": {
            "context": "text",
            "field": "nonexistent_field",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "ServerGenericError": {
        "type": "object",
        "description": "Error returned with `code` `ServerGeneric` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ServerGeneric` — a plain server-side error wrapped into the API\n    envelope. `error` carries the underlying message. The suggest\n    endpoint produces this for a malformed request: invalid JSON (in the\n    request body, or in the `BODY` query parameter on the GET form), an\n    objecttype in `objecttypes` or `linked_objecttypes` that does not\n    exist (`Objecttype %q not found`), an unknown `tokens_mode`\n    (`Unknown tokens_mode %q`), or an entry in `fields` that cannot be\n    resolved.\n",
            "enum": [
              "ServerGeneric"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `msg`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "ServerGeneric",
          "error": "Server error occurred: Unknown tokens_mode \"fuzzy\".",
          "package": "ferrors",
          "parameters": {
            "msg": "Unknown tokens_mode \"fuzzy\"",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "ShareLinkAliasInvalidError": {
        "type": "object",
        "description": "Error returned with `code` `ShareLinkAliasInvalid` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ShareLinkAliasInvalid` — the optional `alias` field contains\n    characters outside the RFC 3986 unreserved set, or starts / ends\n    with a non-alphanumeric character.\n",
            "enum": [
              "ShareLinkAliasInvalid"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "share_link"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ShareLinkAlreadyExistsError": {
        "type": "object",
        "description": "Error returned with `code` `ShareLinkAlreadyExists` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ShareLinkAlreadyExists` — a share link with the same path (and\n    alias, if given) is already on file.\n",
            "enum": [
              "ShareLinkAlreadyExists"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "share_link"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "ShareLinkAlreadyExists",
          "error": "A shortened share link already exists for this configuration.",
          "package": "share_link",
          "parameters": {
            "realm": "share_link",
            "statuscode": 400
          },
          "realm": "share_link",
          "statuscode": 400
        }
      },
      "ShareLinkExpirationDateInPastError": {
        "type": "object",
        "description": "Error returned with `code` `ShareLinkExpirationDateInPast` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ShareLinkExpirationDateInPast` — `expires_at` is in the past (or\n    otherwise rejected by the validator).\n",
            "enum": [
              "ShareLinkExpirationDateInPast"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "share_link"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ShareLinkInvalidError": {
        "type": "object",
        "description": "Error returned with `code` `ShareLinkInvalid` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ShareLinkInvalid` — `GET /system/share_link/{id}` was called with\n    an id that does not exist or that has expired.\n",
            "enum": [
              "ShareLinkInvalid"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "share_link"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "ShareLinkPathInvalidError": {
        "type": "object",
        "description": "Error returned with `code` `ShareLinkPathInvalid` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `ShareLinkPathInvalid` — the `path` field in the create payload is\n    empty, malformed, or does not start with `/`.\n",
            "enum": [
              "ShareLinkPathInvalid"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "share_link"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "SkipHeadRequestError": {
        "type": "object",
        "description": "Error returned with `code` `SkipHeadRequestError` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `SkipHeadRequestError` — `POST /eas/rput` for a remote URL could not\n    derive a `filename` from the upstream HEAD response.\n    `parameters.url` carries the remote URL.\n",
            "enum": [
              "SkipHeadRequestError"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "fileupload"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `url`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "StartTimeAfterEndTimeError": {
        "type": "object",
        "description": "Error returned with `code` `StartTimeAfterEndTime` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `StartTimeAfterEndTime` — the message's `start_time` is after its\n    `end_time`; the validity window is empty.\n",
            "enum": [
              "StartTimeAfterEndTime"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "message"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `endtime`, `starttime`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "StartTimeAfterEndTime",
          "error": "The given start time 2000-01-01T00:00:00Z is after the given end time 1999-01-01T00:00:00Z",
          "package": "message",
          "parameters": {
            "starttime": "2000-01-01T00:00:00Z",
            "endtime": "1999-01-01T00:00:00Z",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "SystemRightRequiredError": {
        "type": "object",
        "description": "Error returned with `code` `SystemRightRequired` (HTTP `403`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `SystemRightRequired` — the caller holds none of the system rights\n    the operation requires. `parameters.rights` lists the system rights\n    that would have satisfied the check.\n",
            "enum": [
              "SystemRightRequired"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `rights`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              403
            ],
            "description": "The HTTP status code, repeated here. Always `403`."
          }
        },
        "example": {
          "code": "SystemRightRequired",
          "error": "You do not have sufficient permissions to grant this right. One of the following system rights is required: [\"system.api.event[get], system.root\"].",
          "package": "acl",
          "parameters": {
            "rights": "system.api.event[get], system.root",
            "realm": "api",
            "statuscode": 403
          },
          "realm": "api",
          "statuscode": 403
        }
      },
      "TagNotEnabledError": {
        "type": "object",
        "description": "Error returned with `code` `TagNotEnabled` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `TagNotEnabled` — one of the `tag_ids` exists but is not enabled for\n    the requested objecttype/pool combination. `parameters.tagid`\n    carries the offending id. This enum is not exhaustive. Not every 400\n    carries one of the codes above: input-validation failures such as an\n    unknown `pool_id`, an objecttype that has no pool or no tags, or a\n    `db_info/update` call missing `objecttype`/`object_ids`, are\n    returned as generic 400 messages without a stable `code`. Other 400\n    codes from the server pipeline (request parsing, `ReadOnlyMode`, …)\n    may also surface here. Always tolerate codes outside this enum.\n",
            "enum": [
              "TagNotEnabled"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "dbinfo"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `tagid`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "TagNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `TagNotFound` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `TagNotFound` — one of the `tag_ids` in the request body does not\n    match any tag. `parameters.tagid` carries the offending id.\n",
            "enum": [
              "TagNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "dbinfo"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `tagid`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "TagsInUseError": {
        "type": "object",
        "description": "Error returned with `code` `TagsInUse` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `TagsInUse` — one or more tags that would be deleted are still\n    referenced elsewhere in the system and cannot be removed\n    automatically. This endpoint has no DELETE method; any tag not\n    present in the request is deleted, and the request fails if any of\n    those deletions would orphan a reference. `parameters.usages` lists\n    every place each tag is still in use so the caller can resolve the\n    reference manually before retrying. Other 400 codes from the server\n    pipeline (request parsing, `ReadOnlyMode`, …) may also surface here.\n",
            "enum": [
              "TagsInUse"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "tag"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `usages`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "TagsInUse",
          "error": "The tags can not be deleted, because they are used in 10 places where they have to be deleted manually",
          "package": "tag",
          "realm": "api",
          "statuscode": 400,
          "parameters": {
            "realm": "api",
            "statuscode": 400,
            "usages": [
              {
                "tag_id": 5,
                "context": "baseconfig",
                "refs": [
                  "system.config.oai_pmh.tagfilter_deleted",
                  "plugin.fylr-plugin-search-presets.config.presets[0].tagfilter"
                ]
              },
              {
                "tag_id": 5,
                "context": "object",
                "ids": [
                  1042,
                  1043,
                  1099
                ]
              },
              {
                "tag_id": 5,
                "context": "pool._acl",
                "ids": [
                  2,
                  7
                ]
              },
              {
                "tag_id": 8,
                "context": "objecttype._acl",
                "ids": [
                  42
                ]
              },
              {
                "tag_id": 8,
                "context": "right_preset._acl",
                "ids": [
                  11,
                  14
                ]
              },
              {
                "tag_id": 8,
                "context": "tag._acl",
                "ids": [
                  21
                ]
              },
              {
                "tag_id": 12,
                "context": "objecttype._columnfilters",
                "ids": [
                  42,
                  57
                ]
              },
              {
                "tag_id": 12,
                "context": "objecttype._maskfilters",
                "ids": [
                  57
                ]
              },
              {
                "tag_id": 12,
                "context": "transition.tagfilter:after",
                "ids": [
                  3,
                  4
                ]
              },
              {
                "tag_id": 12,
                "context": "transition.tagfilter:before",
                "ids": [
                  3
                ]
              }
            ]
          }
        }
      },
      "TypeChangeUnsupportedError": {
        "type": "object",
        "description": "Error returned with `code` `TypeChangeUnsupported` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `TypeChangeUnsupported` — an existing column's type cannot be\n    changed to the requested one — the conversion path isn't\n    implemented.\n",
            "enum": [
              "TypeChangeUnsupported"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `column`, `current`, `head`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UnableToSetIsSystemPoolError": {
        "type": "object",
        "description": "Error returned with `code` `UnableToSetIsSystemPool` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnableToSetIsSystemPool` — `is_system_pool` cannot be set or\n    changed through the API; system pools are seeded at install time\n    only. Raised on POST/PUT.\n",
            "enum": [
              "UnableToSetIsSystemPool"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "pool"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UnableToSetPasswordForUserTypeError": {
        "type": "object",
        "description": "Error returned with `code` `UnableToSetPasswordForUserType` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnableToSetPasswordForUserType` — the user `type` does not allow\n    setting a password (e.g. SSO-only types).\n",
            "enum": [
              "UnableToSetPasswordForUserType"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `type`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UnknownColumnTypeError": {
        "type": "object",
        "description": "Error returned with `code` `UnknownColumnType` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnknownColumnType` — a column requests a type unknown to this fylr\n    release (or to the loaded plugins).\n",
            "enum": [
              "UnknownColumnType"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "datamodel"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `type`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UnknownFieldError": {
        "type": "object",
        "description": "Error returned with `code` `UnknownField` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnknownField` — the template references a field name that does not\n    exist on the objecttype. `parameters.field` carries the offending\n    api field name. Message: `Unknown field \u003cfield\u003e`.\n",
            "enum": [
              "UnknownField"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "objecttype"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `field`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "UnknownField",
          "error": "Unknown field subtitel.",
          "package": "objecttype",
          "parameters": {
            "field": "subtitel",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "UnknownObjecttypeError": {
        "type": "object",
        "description": "Error returned with `code` `UnknownObjecttype` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnknownObjecttype` — the object type or mask in the URL does not\n    exist. Other 400s on this endpoint (missing object ID, unparseable\n    query parameter, …) come from generic bad-request validation without\n    a stable `code`.\n",
            "enum": [
              "UnknownObjecttype"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `objecttype`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "UnknownObjecttype",
          "error": "Unknown object type pictures.",
          "package": "api",
          "parameters": {
            "objecttype": "pictures",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "UnknownRightError": {
        "type": "object",
        "description": "Error returned with `code` `UnknownRight` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnknownRight` — the preset references a right name that does not\n    exist in the addressed context. `parameters.right` carries the\n    offending name, `parameters.context` the context.\n",
            "enum": [
              "UnknownRight"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "rightcheck"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `context`, `right`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "UnknownRight",
          "error": "The right \"supervise\" is not known in context \"object\".",
          "package": "rightcheck",
          "parameters": {
            "right": "supervise",
            "context": "object",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "UnknownRightParamError": {
        "type": "object",
        "description": "Error returned with `code` `UnknownRightParam` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnknownRightParam` — the preset sets a parameter that the addressed\n    right does not declare. `parameters.param` carries the offending\n    name, `parameters.right` / `parameters.right_displayname` identify\n    the right.\n",
            "enum": [
              "UnknownRightParam"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "rightcheck"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `context`, `param`, `right`,\n`rightdisplayname`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UnknownRightValueError": {
        "type": "object",
        "description": "Error returned with `code` `UnknownRightValue` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnknownRightValue` — a parameter's value is not in the right's\n    `choices` (or fails the right's value validation).\n    `parameters.value` carries what was sent.\n",
            "enum": [
              "UnknownRightValue"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "rightcheck"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `right`, `rightdisplayname`, `value`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UnknownTimezoneError": {
        "type": "object",
        "description": "Error returned with `code` `UnknownTimezone` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnknownTimezone` — the request's `timezone` is not a known timezone\n    identifier.\n",
            "enum": [
              "UnknownTimezone"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "search"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `timezone`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UnsupportedFieldTypeError": {
        "type": "object",
        "description": "Error returned with `code` `UnsupportedFieldType` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnsupportedFieldType` — the template references a field that is\n    neither a files column nor a link to an objecttype that has a files\n    column. `parameters.field` and `parameters.type` carry the field\n    name and its column type. Message: `Unsupported type \u003ctype\u003e for\n    field \u003cfield\u003e`. These are common values, not an exhaustive list:\n    other 400 codes from the save pipeline and the datamodel validator\n    may also surface here (see the operation's 400 description).\n",
            "enum": [
              "UnsupportedFieldType"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "objecttype"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `field`, `type`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UnsupportedInAggregationError": {
        "type": "object",
        "description": "Error returned with `code` `UnsupportedInAggregation` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UnsupportedInAggregation` — an aggregation uses an unsupported\n    combination of options.\n",
            "enum": [
              "UnsupportedInAggregation"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "search"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `agg`, `unsupported`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UploadError": {
        "type": "object",
        "description": "Error returned with `code` `UploadError` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UploadError` — an error occurred while reading the upload body.\n    `parameters.filename` carries the file name from the multipart part.\n    Wrapped underlying error in `error`.\n",
            "enum": [
              "UploadError"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "fileupload"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `filename`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UserArchivedError": {
        "type": "object",
        "description": "Error returned with `code` `UserArchived` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserArchived` — the user payload is `_archived` and cannot be saved\n    (only un-archived users can be modified).\n",
            "enum": [
              "UserArchived"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UserDeletePolicyError": {
        "type": "object",
        "description": "Error returned with `code` `UserDeletePolicy` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserDeletePolicy` — `delete_policy` was supplied but is not allowed\n    for user deletion.\n",
            "enum": [
              "UserDeletePolicy"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UserDeleteSelfError": {
        "type": "object",
        "description": "Error returned with `code` `UserDeleteSelf` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserDeleteSelf` — the requester is attempting to delete their own\n    account.\n",
            "enum": [
              "UserDeleteSelf"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UserDuplicateEmailError": {
        "type": "object",
        "description": "Error returned with `code` `UserDuplicateEmail` (HTTP `409`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserDuplicateEmail` — another user has the same email address.\n    `parameters.email` carries the email, `parameters.name` the name of\n    the existing user.\n",
            "enum": [
              "UserDuplicateEmail"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `email`, `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              409
            ],
            "description": "The HTTP status code, repeated here. Always `409`."
          }
        },
        "example": {
          "code": "UserDuplicateEmail",
          "error": "Email \"alice@example.com\" already exists. User: alice.",
          "package": "acl",
          "parameters": {
            "email": "alice@example.com",
            "name": "alice",
            "realm": "api",
            "statuscode": 409
          },
          "realm": "api",
          "statuscode": 409
        }
      },
      "UserDuplicateLoginError": {
        "type": "object",
        "description": "Error returned with `code` `UserDuplicateLogin` (HTTP `409`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserDuplicateLogin` — another user has the same login.\n    `parameters.login` and `parameters.name` carry the details.\n",
            "enum": [
              "UserDuplicateLogin"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `login`, `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              409
            ],
            "description": "The HTTP status code, repeated here. Always `409`."
          }
        }
      },
      "UserEmailMalformedError": {
        "type": "object",
        "description": "Error returned with `code` `UserEmailMalformed` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserEmailMalformed` — the email field is not RFC-acceptable. Other\n    400 codes from the server pipeline (request parsing, `ReadOnlyMode`,\n    …) may also surface here.\n",
            "enum": [
              "UserEmailMalformed"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `email`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        },
        "example": {
          "code": "UserEmailMalformed",
          "error": "The email \"not-an-email\" is not acceptable.",
          "package": "acl",
          "parameters": {
            "email": "not-an-email",
            "realm": "api",
            "statuscode": 400
          },
          "realm": "api",
          "statuscode": 400
        }
      },
      "UserLimitNotAllowedError": {
        "type": "object",
        "description": "Error returned with `code` `UserLimitNotAllowed` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserLimitNotAllowed` — the limit operation would lock the requester\n    (or any other system user) out.\n",
            "enum": [
              "UserLimitNotAllowed"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UserNotFoundError": {
        "type": "object",
        "description": "Error returned with `code` `UserNotFound` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserNotFound` — no stored user matches the id in the URL of `GET\n    /user/{id}` (returned as `400`, not `404`).\n",
            "enum": [
              "UserNotFound"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`. This code is raised from:\n`acl`, `oauth`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UserPictureNoRightsError": {
        "type": "object",
        "description": "Error returned with `code` `UserPictureNoRights` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserPictureNoRights` — the user picture supplied was not uploaded\n    by the current user.\n",
            "enum": [
              "UserPictureNoRights"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "UserRequiredError": {
        "type": "object",
        "description": "Error returned with `code` `UserRequired` (HTTP `401`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserRequired` — the request did not carry a valid access token.\n",
            "enum": [
              "UserRequired"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "ferrors"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              401
            ],
            "description": "The HTTP status code, repeated here. Always `401`."
          }
        },
        "example": {
          "code": "UserRequired",
          "error": "The API call requires an authenticated user.",
          "package": "ferrors",
          "parameters": {
            "realm": "api",
            "statuscode": 401
          },
          "realm": "api",
          "statuscode": 401
        }
      },
      "UserTypeNotAllowedError": {
        "type": "object",
        "description": "Error returned with `code` `UserTypeNotAllowed` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `UserTypeNotAllowed` — the requested user `type` (e.g. `easydb`,\n    `easydb_idm`) is not enabled on this instance.\n",
            "enum": [
              "UserTypeNotAllowed"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `type`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "VersionMismatchError": {
        "type": "object",
        "description": "Error returned with `code` `VersionMismatch` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `VersionMismatch` — on update, the supplied `_version` was not the\n    stored version + 1. Other 400 codes from the server pipeline\n    (request parsing, ...) may also surface here.\n",
            "enum": [
              "VersionMismatch"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`. This code is raised from:\n`ferrors`, `object`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `currentversion`, `expected`,\n`expectedversion`, `got`, `object`, `receivedversion`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "WarningExportFileError": {
        "type": "object",
        "description": "Error returned with `code` `WarningExportFile` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `WarningExportFile` — a non-fatal warning surfaced during a download\n    — the response carries the message so the front end can show it next\n    to the file.\n",
            "enum": [
              "WarningExportFile"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `id`, `name`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "WebdavNotEnabledError": {
        "type": "object",
        "description": "Error returned with `code` `WebdavNotEnabled` (HTTP `503`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `WebdavNotEnabled` — the instance has the WebDAV endpoint turned off\n    in its base config (`webdav.read_write_access = false`).\n",
            "enum": [
              "WebdavNotEnabled"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              503
            ],
            "description": "The HTTP status code, repeated here. Always `503`."
          }
        },
        "example": {
          "code": "WebdavNotEnabled",
          "error": "WebDAV access is not enabled.",
          "package": "api",
          "parameters": {
            "realm": "api",
            "statuscode": 503
          },
          "realm": "api",
          "statuscode": 503
        }
      },
      "WildcardExpandedToTooManyTermsError": {
        "type": "object",
        "description": "Error returned with `code` `WildcardExpandedToTooManyTerms` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `WildcardExpandedToTooManyTerms` — a wildcard expanded to more terms\n    than the configured limit; narrow the term.\n",
            "enum": [
              "WildcardExpandedToTooManyTerms"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "search"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `termlimit`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "WildcardOnlyNotAllowedError": {
        "type": "object",
        "description": "Error returned with `code` `WildcardOnlyNotAllowed` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `WildcardOnlyNotAllowed` — a `text` search on this field consists\n    only of wildcards, which is not allowed.\n",
            "enum": [
              "WildcardOnlyNotAllowed"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "search"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details: `field`.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "WrongPasswordError": {
        "type": "object",
        "description": "Error returned with `code` `WrongPassword` (HTTP `400`).\n",
        "required": [
          "code",
          "error",
          "package",
          "parameters",
          "realm",
          "statuscode"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code:\n\n  * `WrongPassword` — `/user/change_password` was called with a wrong\n    current password.\n",
            "enum": [
              "WrongPassword"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable message, localized to the caller's preferred language.\nIf no translation exists for this error key, the untranslated message\nis returned with a `Package` / `Code` footer appended.\n"
          },
          "package": {
            "type": "string",
            "enum": [
              "acl"
            ],
            "description": "Internal origin marker for **fylr** support; not part of the API\ncontract. Branch on `code`, not `package`.\n"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Machine-readable details; `realm` and `statuscode` are repeated here.\n"
          },
          "realm": {
            "type": "string",
            "enum": [
              "api"
            ],
            "description": "The realm the error originates from. Always `api`."
          },
          "statuscode": {
            "type": "integer",
            "enum": [
              400
            ],
            "description": "The HTTP status code, repeated here. Always `400`."
          }
        }
      },
      "DbObject": {
        "type": "object",
        "description": "A **fylr** object as exchanged with the `/db/{objecttype}` endpoint. Every\nobject carries the system fields below. The content fields live in a nested\nobject whose key is the object type name; which fields are present depends on\nthe object type and the `_mask`. The object-type-specific sections of this\ndocumentation describe those fields concretely.\n",
        "required": [
          "_objecttype",
          "_mask"
        ],
        "properties": {
          "_objecttype": {
            "type": "string",
            "description": "Name of the object type. Matches `{objecttype}` in the URL."
          },
          "_mask": {
            "type": "string",
            "description": "Name of the mask that shapes the object. The mask selects which fields\nare present and whether each is writable or read-only.\n"
          },
          "_system_object_id": {
            "type": "integer",
            "description": "Instance-wide unique ID of the object. Settable while the object is\nversion 1 (new), immutable afterwards.\n"
          },
          "_global_object_id": {
            "type": "string",
            "format": "\u003c_system_object_id\u003e@\u003cdatabase uuid\u003e",
            "description": "Globally unique object ID: the `_system_object_id` followed by\n`@\u003cdatabase name\u003e`.\n"
          },
          "_uuid": {
            "type": "string",
            "description": "System-wide unique identifier for the object."
          },
          "_owner": {
            "$ref": "#/components/schemas/WhoApi",
            "description": "The owner of the object; may be a user or a group."
          },
          "_created": {
            "type": "string",
            "format": "date_iso8601",
            "description": "The datetime the object was created."
          },
          "{objecttype}": {
            "type": "object",
            "description": "Content of the object, in a property named after the object type. Holds\n`_id`, `_version` and the fields defined by the object type and selected\nby the `_mask`.\n",
            "properties": {
              "_id": {
                "type": "integer",
                "description": "ID of the object, unique within the object type. Settable while the\nobject is version 1 (new), immutable afterwards.\n"
              },
              "_version": {
                "type": "integer",
                "description": "Version of the object. Starts at 1 and is incremented on every\nupdate; an update must send the current version.\n"
              }
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "GroupApi": {
        "type": "object",
        "description": "A user **group**. Bundles a set of users together so the ACL system\ncan address them collectively.\n",
        "required": [
          "_basetype",
          "group"
        ],
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "group"
            ],
            "description": "Fixed marker identifying this object as a group."
          },
          "group": {
            "type": "object",
            "description": "The mutable group data.",
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64",
                "description": "Server-issued numeric id of the group. Required for updates."
              },
              "_version": {
                "type": "integer",
                "format": "int64",
                "description": "Version of the group; increment on each update."
              },
              "reference": {
                "type": "string",
                "description": "Optional unique reference. Lets clients address the group by a\nstable string identifier instead of `_id`.\n"
              },
              "name": {
                "type": "string",
                "description": "Internal name of the group (unique)."
              },
              "comment": {
                "type": "string",
                "description": "Free-text comment, admin-facing."
              },
              "category_a": {
                "type": "string",
                "description": "Optional category label A."
              },
              "category_b": {
                "type": "string",
                "description": "Optional category label B."
              },
              "category_c": {
                "type": "string",
                "description": "Optional category label C."
              },
              "displayname": {
                "$ref": "#/components/schemas/LocaValue"
              },
              "frontend_prefs": {
                "type": "object",
                "additionalProperties": true,
                "description": "Arbitrary frontend-only preferences stored with the group."
              },
              "type": {
                "type": "string",
                "enum": [
                  "easydb",
                  "system"
                ],
                "description": "Group type. One of `easydb` (a normal user group) or `system`\n(an internal, immutable group). New groups default to `easydb`.\nCreating a group with `type: system` is rejected with\n`GroupTypeNotAllowed`, and an existing group's `type` cannot be\nchanged (`GroupTypeChangeNotAllowed`).\n"
              },
              "lookup:_id": {
                "$ref": "#/components/schemas/LookupByReference",
                "description": "Optional lookup descriptor used to resolve `_id` from the\ngroup's `reference` server-side.\n"
              }
            }
          },
          "_generated_rights": {
            "$ref": "#/components/schemas/GeneratedRightsApi",
            "description": "Read-only per-session derivation of the rights the current user\nholds on this group.\n"
          },
          "_acl": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RightApi"
            },
            "description": "ACL grants on this group."
          },
          "_system_rights": {
            "$ref": "#/components/schemas/SystemRightsApi",
            "description": "System rights granted to members of this group."
          },
          "_pseudonymization": {
            "$ref": "#/components/schemas/GroupPseudoApi",
            "description": "Pseudonymization configuration for members of this group."
          },
          "_auth_method_group_maps": {
            "$ref": "#/components/schemas/AuthMethodGroupMapsApi",
            "description": "Mappings between external auth providers (LDAP / SAML / OAuth)\nand this group — controls which incoming auth subjects are\nassigned to the group.\n"
          },
          "_ip_subnet_filter": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "CIDR / subnet entries. If set, members of this group can only sign\nin from a matching network — unless `_ip_subnet_filter_exclude` is\ntrue, in which case the matching networks are denied.\n"
          },
          "_ip_subnet_filter_exclude": {
            "type": "boolean",
            "description": "Invert the meaning of `_ip_subnet_filter`."
          },
          "_two_fa_required": {
            "type": "boolean",
            "description": "If true, members of this group must pass a second authentication factor\n(email one-time code / TOTP) at login, when two-factor authentication is\nenabled in the base config. Defaults to false.\n"
          },
          "_owner": {
            "$ref": "#/components/schemas/WhoApi",
            "description": "The group's owner. The grant `who._owner: true` resolves to\nthis principal.\n"
          },
          "_created_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the group was created."
          },
          "_updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the group was last updated."
          },
          "_automatic_auth": {
            "$ref": "#/components/schemas/AutomaticAuthApi",
            "description": "Automatic-auth descriptor (one-time token, expiry, etc.)."
          }
        }
      },
      "UserApi": {
        "type": "object",
        "description": "A **user** record. Used as the request and response body of the\n`/api/v1/user*` endpoints.\n",
        "required": [
          "_basetype",
          "user"
        ],
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "user"
            ],
            "description": "Fixed marker identifying this object as a user."
          },
          "user": {
            "type": "object",
            "description": "The mutable user data.",
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64",
                "description": "Server-issued numeric id. Required for updates."
              },
              "_version": {
                "type": "integer",
                "format": "int64",
                "description": "Version; increment on each update."
              },
              "login": {
                "type": "string",
                "maxLength": 500,
                "description": "Login name (unique). Required for password-based user types.\n"
              },
              "reference": {
                "type": "string",
                "description": "Optional unique reference. Lets clients address the user by a\nstable string identifier instead of `_id`.\n"
              },
              "type": {
                "type": "string",
                "description": "User type (e.g. `easydb`, `easydb_ldap`, `easydb_sso`,\n`easydb_oauth`, `system`). Determines whether a password can\nbe set and which auth pipeline is consulted on login.\n"
              },
              "frontend_language": {
                "type": "string",
                "description": "Preferred UI language as a BCP-47 tag (`de-DE`, `en-US`, ...).\n"
              },
              "database_languages": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Languages the user is allowed to edit / see data values in.\n"
              },
              "frontend_prefs": {
                "type": "object",
                "additionalProperties": true,
                "description": "Arbitrary frontend-only preferences stored on the user."
              },
              "custom_data": {
                "type": "object",
                "additionalProperties": true,
                "description": "Custom-data values (per the datamodel's user customisation)."
              },
              "first_name": {
                "type": "string"
              },
              "last_name": {
                "type": "string"
              },
              "displayname": {
                "type": "string",
                "description": "Rendered display name. Either set explicitly or derived from\n`first_name` / `last_name` / `login`.\n"
              },
              "company": {
                "type": "string"
              },
              "department": {
                "type": "string"
              },
              "phone": {
                "type": "string"
              },
              "remarks": {
                "type": "string"
              },
              "address_supplement": {
                "type": "string"
              },
              "street": {
                "type": "string"
              },
              "house_number": {
                "type": "string"
              },
              "postal_code": {
                "type": "string"
              },
              "town": {
                "type": "string"
              },
              "state": {
                "type": "string"
              },
              "country": {
                "type": "string"
              },
              "login_disabled": {
                "type": "boolean",
                "description": "If true, the user cannot sign in."
              },
              "login_valid_from": {
                "type": "string",
                "format": "date",
                "description": "Lower bound of the login window. Logins before this date are\nrejected with `LoginValidFrom`. Settable for every user type:\nthe window is enforced by fylr for every authentication\nmethod, including `ldap` and `sso`.\n"
              },
              "login_valid_to": {
                "type": "string",
                "format": "date",
                "description": "Upper bound of the login window. Logins after this date are\nrejected with `LoginValidTo`. Settable for every user type,\nlike `login_valid_from`.\n"
              },
              "require_password_change": {
                "type": "boolean",
                "description": "If true, the next successful login must immediately change\nthe password before any other operation succeeds.\n"
              },
              "mail_schedule": {
                "$ref": "#/components/schemas/ScheduleApi",
                "description": "When (and how often) fylr sends notification mails to this user.\n"
              },
              "email": {
                "type": "string",
                "format": "email",
                "description": "Primary email address. Must be RFC-acceptable; otherwise\n`UserEmailMalformed` is raised on save.\n"
              },
              "confirm_email": {
                "type": "boolean",
                "description": "If true, the user has to confirm their email by clicking the\nlink sent on save before login is allowed.\n"
              },
              "confirm_email_sent_at": {
                "type": "string",
                "format": "date-time",
                "description": "When the confirmation mail was last sent."
              },
              "email_confirmed_at": {
                "type": "string",
                "format": "date-time",
                "description": "When the user confirmed their email."
              },
              "welcome_email": {
                "type": "boolean",
                "description": "If true, a welcome mail is sent on user creation.\n"
              },
              "welcome_email_sent_at": {
                "type": "string",
                "format": "date-time",
                "description": "When the welcome mail was sent."
              },
              "lookup:_id": {
                "$ref": "#/components/schemas/LookupByReference",
                "description": "Optional lookup descriptor used to resolve `_id` from the\nuser's `reference` server-side.\n"
              }
            }
          },
          "_generated_rights": {
            "$ref": "#/components/schemas/GeneratedRightsApi",
            "description": "Read-only per-session derivation of the rights the requester\nholds on this user.\n"
          },
          "_groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GroupApi"
            },
            "description": "Groups this user belongs to. On write, the array may carry full\ngroup payloads or just `{_id: N}` references.\n"
          },
          "_password": {
            "type": "string",
            "maxLength": 100,
            "description": "Plaintext password (write-only). Set on user creation to seed a\npassword; otherwise use `POST /user/change_password`. Never echoed\nback in responses.\n"
          },
          "_acl": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RightApi"
            },
            "description": "ACL grants on the user."
          },
          "_system_rights": {
            "$ref": "#/components/schemas/SystemRightsApi",
            "description": "System rights granted directly to the user."
          },
          "_owner": {
            "$ref": "#/components/schemas/WhoApi",
            "description": "The user's owner. The grant `who._owner: true` resolves to\nthis principal.\n"
          },
          "_collection_pin_codes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserCollectionPinCodeApi"
            },
            "description": "Per-collection PIN codes the user holds (for pin-protected\ncollections).\n"
          },
          "_password_hash": {
            "type": "string",
            "description": "The stored password hash. Only returned when `include_password=true`\nis set and the requester holds `system.root` — used by backup\ntooling.\n"
          },
          "_two_factor_totp_enrolled": {
            "type": "boolean",
            "description": "Read-only. True when the user has a confirmed authenticator-app (TOTP)\nsecond factor enrolled (ticket #78550). Surfaced in the admin user editor.\n"
          },
          "_two_factor_passkey_enrolled": {
            "type": "boolean",
            "description": "Read-only. True when the user has a passkey (WebAuthn) second factor\nenrolled (ticket #78550).\n"
          },
          "_two_factor_last_method": {
            "type": "string",
            "enum": [
              "email",
              "totp",
              "passkey"
            ],
            "description": "Read-only. The two-factor method the user last completed; a returning\nuser is sent straight to it at login (switchable on the page).\n"
          },
          "_two_factor_reset_totp": {
            "type": "boolean",
            "description": "Write-only action. Set `true` to clear the user's authenticator (TOTP)\nenrollment, forcing re-enrollment at next login. Available to admins via\nthe user editor and to the user themselves via the settings dialog\n(self-service). The user's other two-factor state is preserved across\nnormal edits.\n"
          },
          "_two_factor_reset_passkey": {
            "type": "boolean",
            "description": "Write-only action like `_two_factor_reset_totp`, clearing the user's\npasskey (WebAuthn) enrollment.\n"
          },
          "_created_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the user was created."
          },
          "_updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the user was last updated."
          },
          "_archived_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the user was archived. Archived users cannot sign in\n(login fails with `LoginUserArchived`) and cannot be modified.\n"
          },
          "_last_seen_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time of the user's most recent activity."
          }
        }
      },
      "SessionApi": {
        "type": "object",
        "description": "A **session** descriptor — returned by `GET /api/v1/user/session`.\nCarries the access token, the authenticated user and their groups,\nthe system rights they hold, available authentication methods, and\ninstance-wide defaults the front end needs to render correctly.\n",
        "required": [
          "access_token"
        ],
        "properties": {
          "access_token": {
            "type": "string",
            "description": "The session's access token. Use it as the `Bearer` token (or in\nthe `x-fylr-authorization` / `Authorization` header) for\nsubsequent requests.\n"
          },
          "user": {
            "$ref": "#/components/schemas/UserApi"
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GroupApi"
            },
            "description": "Groups the authenticated user belongs to."
          },
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Per-session configuration block — feature flags, theme,\ncache-id, and other values the front end consults at every page\nload.\n"
          },
          "frontend_language": {
            "type": "string",
            "description": "The user's preferred UI language as a BCP-47 tag (`de-DE`,\n`en-US`, ...).\n"
          },
          "database_locales": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LocaleApi"
            },
            "description": "Locales the user is allowed to edit data values in (a richer\nview of `user.database_languages` with locale metadata).\n"
          },
          "system_rights": {
            "$ref": "#/components/schemas/SystemRightsApi",
            "description": "Resolved system-right map. Keys are right names\n(`system.root`, `system.export`, ...); values describe the\neffective grant.\n"
          },
          "authentication_methods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionAuthenticationMethodApi"
            },
            "description": "The authentication methods this instance exposes for the\nsession.\n"
          },
          "authenticated": {
            "$ref": "#/components/schemas/SessionAuthenticationMethodApi",
            "description": "The authentication method the current session was established\nwith. Omitted for anonymous sessions.\n"
          },
          "frontend_locale": {
            "$ref": "#/components/schemas/LocaleApi",
            "description": "Locale metadata (number format, calendar patterns) for the\nuser's `frontend_language`.\n"
          },
          "current_max_event_id": {
            "type": "integer",
            "format": "int64",
            "description": "The latest `_id` issued in the event log when the session was\nbuilt. Pass it as `fromEventId` to `/api/v1/event/poll/{fromEventId}`\nto subscribe to subsequent events.\n"
          },
          "instance": {
            "type": "object",
            "additionalProperties": true,
            "description": "Instance-wide settings the front end needs on every page load\n(display name, external URL, support address, version, ...).\n"
          }
        }
      },
      "PoolApi": {
        "type": "object",
        "x-recursion": true,
        "description": "A storage **pool** — fylr's hierarchical container for objects, ACL\nrules, tag policy and per-objecttype default masks.\n",
        "required": [
          "_basetype",
          "pool"
        ],
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "pool"
            ],
            "description": "Fixed marker identifying this object as a pool."
          },
          "pool": {
            "type": "object",
            "description": "The mutable pool data.",
            "additionalProperties": true,
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64",
                "description": "Server-issued numeric id. Required for updates."
              },
              "_version": {
                "type": "integer",
                "format": "int64"
              },
              "reference": {
                "type": "string",
                "description": "Optional unique reference. Lets clients address the pool by a\nstable string identifier instead of `_id`.\n"
              },
              "name": {
                "$ref": "#/components/schemas/LocaValue"
              },
              "shortname": {
                "$ref": "#/components/schemas/LocaValue"
              },
              "_id_parent": {
                "type": "integer",
                "format": "int64",
                "description": "Parent pool id. `null`/absent for root pools. Creating or\nre-parenting a pool under a parent requires the `bag_create`\nright on that parent; other changes may require additional\nBAG rights (`bag_write`, `bag_acl`). A non-root pool saved\nwithout a parent is rejected with code `PoolNeedsParent`.\n"
              },
              "lookup:_id_parent": {
                "$ref": "#/components/schemas/LookupByReference",
                "description": "Optional lookup descriptor for `_id_parent` — resolve the\nparent pool by `reference` server-side.\n"
              },
              "comment": {
                "type": "string",
                "description": "Free-text comment on the pool."
              },
              "description": {
                "$ref": "#/components/schemas/LocaValue",
                "description": "Localized long description of the pool."
              },
              "contact": {
                "$ref": "#/components/schemas/WhoApi",
                "description": "The pool's contact principal (user or group).\n"
              },
              "is_system_pool": {
                "type": "boolean",
                "description": "Read-only marker for built-in system pools. It cannot be set\nor changed through the API — sending a value that creates or\nchanges it is rejected with code `UnableToSetIsSystemPool`.\n"
              },
              "watermark": {
                "$ref": "#/components/schemas/WatermarkApi",
                "description": "Watermark configuration applied to image variants produced\nfrom objects in this pool. Changing it on save can trigger a\n202 re-sync prompt (see the `confirm` parameter on POST/PUT).\n"
              },
              "caption": {
                "$ref": "#/components/schemas/CaptionByFieldApi",
                "description": "Per-field caption configuration for objects in this pool.\nChanging it on save can trigger a 202 re-sync prompt.\n"
              },
              "janitor_policy": {
                "$ref": "#/components/schemas/JanitorPolicyApi",
                "description": "Janitor (retention/clean-up) policy applied to objects in\nthis pool.\n"
              },
              "custom_data": {
                "type": "object",
                "additionalProperties": true,
                "description": "Custom-data values attached to the pool (per the datamodel's\npool customisation).\n"
              },
              "mapping_dc_export": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "integer",
                    "format": "int64"
                  }
                ],
                "description": "Dublin-Core export mapping for the pool — a mapping\n`reference` (string) or its numeric id.\n"
              },
              "mapping_image_export": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "integer",
                    "format": "int64"
                  }
                ],
                "description": "Image-export mapping for the pool — a mapping `reference`\n(string) or its numeric id.\n"
              },
              "mapping_image_import": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "integer",
                    "format": "int64"
                  }
                ],
                "description": "Image-import mapping for the pool — a mapping `reference`\n(string) or its numeric id.\n"
              }
            }
          },
          "_has_children": {
            "type": "boolean",
            "description": "Read-only flag indicating that at least one sub-pool exists.\nUseful for tree-view rendering without an extra query.\n"
          },
          "_private_acl": {
            "type": "boolean",
            "description": "If true, this pool's ACL is private — it does not inherit ACL\nitems from its parent.\n"
          },
          "_acl": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RightApi"
            },
            "description": "ACL grants on this pool."
          },
          "_generated_rights": {
            "$ref": "#/components/schemas/GeneratedRightsApi",
            "description": "Read-only per-session derivation of the rights the requester\nholds on this pool.\n"
          },
          "_private_transitions": {
            "type": "boolean",
            "description": "If true, this pool's transitions are private — sub-pools do not\ninherit them.\n"
          },
          "_transitions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransitionApi"
            },
            "description": "Workflow transitions exposed on this pool."
          },
          "_private_tags": {
            "type": "boolean",
            "description": "If true, this pool's tags are private — sub-pools do not inherit\nthem.\n"
          },
          "_tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            },
            "description": "Per-pool tag definitions (override the global tag set)."
          },
          "_level": {
            "type": "integer",
            "description": "0 for root pools, +1 for every descent into the tree."
          },
          "_path": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PoolApi"
            },
            "description": "Array of ancestor pools from the root to the immediate parent,\neach rendered in the `standard` format. Useful for breadcrumbs.\nThe recursion is broken at render time via PoolApi's\n`x-recursion: true` marker.\n"
          },
          "_owner": {
            "$ref": "#/components/schemas/WhoApi",
            "description": "The pool's owner. The grant `who._owner: true` resolves to\nthis principal.\n"
          },
          "_compiled_tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            },
            "description": "Effective tag set — the merge of this pool's tags with the\ninherited tags from ancestors. Each entry is rendered in the\nstandard tag format.\n"
          },
          "_standard_masks": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64"
              }
            },
            "description": "Per-objecttype default mask preference. Map of objecttype id to\nan ordered array of mask ids. The first entry is the preferred\nmask for that objecttype within this pool.\n"
          },
          "_created_at": {
            "type": "string",
            "format": "date-time"
          },
          "_updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "example": {
          "_basetype": "pool",
          "pool": {
            "_version": 1,
            "lookup:_id_parent": {
              "reference": "system:root"
            },
            "reference": "testpool",
            "comment": "horst",
            "name": {
              "de-DE": "Testpool [DE]",
              "en-US": "Testpool [EN]"
            }
          }
        }
      },
      "EventApi": {
        "type": "object",
        "description": "An **event** record. fylr writes events for almost every server-side\nmutation (object insert/update, collection changes, ACL changes,\nemail sends, login, ...).\n",
        "required": [
          "_basetype",
          "event"
        ],
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "event"
            ],
            "description": "Fixed marker identifying this object as an event."
          },
          "event": {
            "type": "object",
            "description": "The event payload.",
            "required": [
              "_id",
              "timestamp"
            ],
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64",
                "description": "Server-issued, monotonically-increasing event id. Used as the\ncursor by `/api/v1/event/poll/{fromEventId}`.\n"
              },
              "type": {
                "type": "string",
                "description": "Event type, e.g. `COLLECTION_INSERT`, `OBJECT_UPDATE`,\n`EMAIL_SENT`, `USER_LOGIN`. The full set is defined by\nfylr and grows over time — clients should treat unknown\nvalues as opaque.\n"
              },
              "object_id": {
                "type": "integer",
                "format": "int64",
                "description": "Object id (per-objecttype) the event relates to. Omitted for\nsystem-level events.\n"
              },
              "object_version": {
                "type": "integer",
                "format": "int64",
                "description": "Object version at the time the event was written."
              },
              "global_object_id": {
                "type": "string",
                "description": "Cross-objecttype identifier (`\u003cobjecttype\u003e:\u003cobject_id\u003e`).\n"
              },
              "system_object_id": {
                "type": "integer",
                "format": "int64",
                "description": "The fylr-internal `_system_object_id` (unique across all\nobjecttypes).\n"
              },
              "schema": {
                "type": "string",
                "description": "Datamodel schema the event was recorded under (`user`,\n`system`, ...).\n"
              },
              "basetype": {
                "type": "string",
                "description": "The basetype of the affected entity (`object`, `collection`,\n`user`, `group`, ...).\n"
              },
              "objecttype": {
                "type": "string",
                "description": "Objecttype name when `basetype: object`.\n"
              },
              "timestamp": {
                "type": "string",
                "format": "date-time",
                "description": "UTC time the event was written."
              },
              "pollable": {
                "type": "boolean",
                "description": "Whether this event is surfaced through the long-poll / stream\nendpoints (vs. only being available via `/event/list`).\n"
              },
              "info": {
                "type": "object",
                "additionalProperties": true,
                "description": "Event-specific structured payload. The keys depend on `type`\n— for example object events carry `field`, `old_value` and\n`new_value`; email events carry `from`, `to` and `subject`.\n"
              },
              "remote_addr": {
                "type": "string",
                "description": "IP address of the request that produced the event, when\navailable.\n"
              },
              "user_generated_displayname": {
                "type": "string",
                "description": "Rendered display name of the user that produced the event\n(snapshot at event time — does not update when the user's\ndisplay name later changes).\n"
              }
            }
          },
          "user": {
            "$ref": "#/components/schemas/WhoApi",
            "description": "Snapshot of the user (or group) that produced the event.\nOmitted for system-generated events.\n"
          }
        }
      },
      "MessageApi": {
        "type": "object",
        "description": "An internal **message** addressed to one or more user groups. Used by\nfylr to display admin notifications, maintenance announcements and\nrelease notes inside the front end.\n",
        "required": [
          "_basetype",
          "message"
        ],
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "message"
            ],
            "description": "Fixed marker identifying this object as a message."
          },
          "_groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GroupApi"
            },
            "description": "Groups the message is addressed to. Only users in at least one\nof these groups see the message.\n"
          },
          "message": {
            "type": "object",
            "description": "The mutable message payload.",
            "required": [
              "title",
              "message"
            ],
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64",
                "description": "Server-issued numeric id. Required for updates."
              },
              "_version": {
                "type": "integer",
                "format": "int64",
                "description": "Object version. Send `1` to create a new message. To update,\nsend the existing version + 1 together with `_id`; a mismatch\nreturns `VersionMismatch` (400).\n"
              },
              "webfrontend_props": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                },
                "description": "Free-form key/value pairs for the front end to consume\n(display location, theme, dismiss button text override, ...).\n"
              },
              "webfrontend_type": {
                "type": "string",
                "description": "The front-end rendering kind (e.g. `banner`, `modal`,\n`toast`).\n"
              },
              "confirm_every_version": {
                "type": "boolean",
                "description": "If true, a confirmation only counts for the exact `_version`\nit was made on, so each new version must be confirmed again.\nIf false, any prior confirmation counts.\n"
              },
              "show_always": {
                "type": "boolean",
                "description": "If true, the message is shown on every page load until\nconfirmed (or until the `end_time` passes). For `show_always`\nmessages, a confirmation older than 60s is ignored so the\nmessage reappears.\n"
              },
              "reference": {
                "type": "string",
                "description": "Optional unique reference. Useful when seeding messages from\ntooling.\n"
              },
              "title": {
                "$ref": "#/components/schemas/LocaValue"
              },
              "message": {
                "$ref": "#/components/schemas/LocaValue"
              },
              "confirmation": {
                "$ref": "#/components/schemas/LocaValue"
              },
              "client_ids": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Restrict the message to specific front-end client ids\n(e.g. mobile app only). Empty means show in every client.\n"
              },
              "start_time": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "value": {
                    "type": "string",
                    "format": "date-time"
                  }
                },
                "description": "When the message becomes visible, wrapped as\n`{ \"value\": \u003cdate-time\u003e }`. Null/omitted means visible\nimmediately. The value is truncated to whole seconds (UTC).\n"
              },
              "end_time": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "value": {
                    "type": "string",
                    "format": "date-time"
                  }
                },
                "description": "When the message stops being visible, wrapped as\n`{ \"value\": \u003cdate-time\u003e }`. Null/omitted means visible until\nconfirmed. Truncated to whole seconds (UTC). Must not be\nbefore `start_time` (else `StartTimeAfterEndTime`, 400).\n"
              }
            }
          },
          "_created_at": {
            "type": "string",
            "format": "date-time"
          },
          "_updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PublishApi": {
        "type": "object",
        "description": "A **publish record** — fylr's note that an object was published in an\nexternal system. fylr does not produce or host the publication itself;\nthis entry links the object to the **collector** it was published\nthrough and to the external URL where the publication lives.\n",
        "required": [
          "_basetype",
          "publish"
        ],
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "publish"
            ],
            "description": "Fixed marker identifying this object as a publish."
          },
          "_timestamp_created": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the publish entry was created."
          },
          "publish": {
            "type": "object",
            "required": [
              "system_object_id",
              "collector",
              "publish_uri",
              "easydb_uri"
            ],
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64",
                "description": "Server-issued numeric id."
              },
              "version": {
                "type": "integer",
                "format": "int64",
                "description": "Optional. When set (\u003e 0) the publication is pinned to that\nexact object version; when omitted it tracks the object's\ncurrent version. Echoed in responses only when an exact\nversion was pinned. **fylr** performs no range validation on\nthis value.\n"
              },
              "system_object_id": {
                "type": "integer",
                "format": "int64",
                "description": "The `_system_object_id` of the object being published.\n"
              },
              "collector": {
                "type": "string",
                "description": "Name of the publish collector — must match a collector\nconfigured in the base config (`internalname`), otherwise the\nrequest is rejected with `PublishUnknownCollector`. Example:\n`datacite`.\n"
              },
              "publish_uri": {
                "type": "string",
                "description": "The URL clients can use to reach the published artifact.\nStored verbatim (only surrounding whitespace is trimmed); fylr\ndoes not validate it as a URI. Must be non-empty, else the\nrequest is rejected with `PublishInvalidData`.\n"
              },
              "easydb_uri": {
                "type": "string",
                "description": "The URL clients can use to reach the source object inside\nfylr (deep-link back into the editor). Stored verbatim (only\nsurrounding whitespace is trimmed); fylr does not validate it\nas a URI. Must be non-empty, else the request is rejected with\n`PublishInvalidData`.\n"
              }
            }
          }
        },
        "example": {
          "_basetype": "publish",
          "publish": {
            "system_object_id": 1,
            "_id": 1,
            "publish_uri": "co456-9885",
            "collector": "datacite",
            "easydb_uri": "/api/objects/UUID/8"
          }
        }
      },
      "ExportApi": {
        "type": "object",
        "description": "An **export** — a long-running job that bundles a set of objects\n(and optionally their files) into a downloadable archive (TAR.GZ or\nZIP).\n",
        "required": [
          "_basetype",
          "export"
        ],
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "export"
            ],
            "description": "Fixed marker identifying this object as an export."
          },
          "export": {
            "type": "object",
            "description": "The mutable export configuration.",
            "required": [
              "type",
              "name",
              "search"
            ],
            "additionalProperties": true,
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64"
              },
              "_version": {
                "type": "integer",
                "format": "int64"
              },
              "type": {
                "type": "string",
                "enum": [
                  "export",
                  "export_incremental",
                  "download"
                ],
                "description": "Export kind. `export` produces a fresh archive every run.\n`export_incremental` only includes objects that changed since\nthe last run. `download` is a single-shot package.\n"
              },
              "name": {
                "type": "string",
                "description": "Human-readable name."
              },
              "search": {
                "$ref": "#/components/schemas/SearchRequest",
                "description": "The search descriptor that selects which objects to include\n(same shape as `POST /api/v1/search`).\n"
              },
              "fields": {
                "type": "object",
                "description": "Per-field export selection. Each KEY is a search/column\napi-name (e.g. `objecttype.field`); unknown keys are rejected,\nand the field's required merge depth must not exceed\n`merge_max_depth`. Each VALUE is an object whose only\nmeaningful property is `display_name`.\n",
                "additionalProperties": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "display_name": {
                      "type": "string",
                      "description": "Optional display name for the exported field."
                    }
                  }
                }
              },
              "eas_fields": {
                "type": "object",
                "description": "Per-asset-field export options, keyed by an asset field's\napi-name (`objecttype.field`). The key must resolve to a\n`files`-type column within `merge_max_depth`.\n",
                "additionalProperties": {
                  "$ref": "#/components/schemas/ExportEasField"
                }
              },
              "classes": {
                "type": "object",
                "description": "Per-file-class rendition defaults. Keyed by file class name\n(e.g. `image`, `audio`, `video`); each value is the ordered\nlist of renditions emitted for every file of that class,\nunless overridden per file via `assets`.\n",
                "additionalProperties": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExportVersion"
                  }
                }
              },
              "assets": {
                "type": "object",
                "description": "Per-file override, keyed by file id. Each value is `true`\n(use the class defaults), `false` (skip the file), or an\nobject selecting an explicit version list.\n",
                "additionalProperties": {
                  "oneOf": [
                    {
                      "type": "boolean"
                    },
                    {
                      "$ref": "#/components/schemas/ExportAsset"
                    }
                  ]
                }
              },
              "csv": {
                "description": "CSV output configuration. Either the literal boolean `false`\n(no CSV output) or a configuration object. Absent CSV is\nechoed back as `false`.\n",
                "oneOf": [
                  {
                    "type": "boolean",
                    "enum": [
                      false
                    ]
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "localized_column_names": {
                        "type": "boolean",
                        "default": false,
                        "description": "If true, column headers use localized display names\ninstead of api-names.\n"
                      },
                      "hierarchy": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "column",
                          "\u003e",
                          "/"
                        ],
                        "default": null,
                        "description": "How object hierarchy/path is rendered in a column.\nEmpty string is treated as unset; any other value is\nrejected.\n"
                      },
                      "include_changelog": {
                        "description": "Either a boolean (legacy: true enables the changelog\nwith user, false clears it) or an object.\n",
                        "oneOf": [
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "object",
                            "additionalProperties": false,
                            "properties": {
                              "with_user": {
                                "type": "boolean",
                                "default": false,
                                "description": "If true, include the changelog user column."
                              }
                            }
                          }
                        ]
                      },
                      "delimiter": {
                        "type": "string",
                        "description": "CSV field delimiter."
                      },
                      "quote": {
                        "type": "string",
                        "description": "CSV quote character."
                      },
                      "escape": {
                        "type": "string",
                        "description": "CSV escape character."
                      },
                      "use_bom": {
                        "type": "boolean",
                        "default": false,
                        "description": "If true, prepend a UTF-8 BOM to the CSV file."
                      }
                    }
                  }
                ]
              },
              "xml": {
                "type": "boolean",
                "description": "Whether to include an XML representation."
              },
              "xml_one_file_per_object": {
                "type": "boolean",
                "description": "If true, every object becomes its own XML file; otherwise a\nsingle XML containing all objects.\n"
              },
              "mapping": {
                "default": "easydb",
                "description": "XML mapping selection. `null` defaults to `easydb`. Accepts\nthe string aliases `easydb` / `easydb_flat`, or a numeric\nmapping-profile id (a positive integer). Other values are\nrejected.\n",
                "oneOf": [
                  {
                    "type": "string",
                    "enum": [
                      "easydb",
                      "easydb_flat"
                    ]
                  },
                  {
                    "type": "integer",
                    "format": "int64",
                    "description": "Numeric XML mapping-profile id."
                  }
                ]
              },
              "xslt_xml_post_processing": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "_id"
                ],
                "description": "XSLT post-processing applied to the rendered XML. References a\nstylesheet file by id; that file must have a `.xsl` or `.xslt`\nextension.\n",
                "properties": {
                  "_id": {
                    "type": "integer",
                    "format": "int64",
                    "description": "File id of the XSLT stylesheet to apply."
                  }
                }
              },
              "xlsx": {
                "description": "XLSX (Excel) output configuration. Either the literal boolean\n`false` (no XLSX output) or a configuration object. Absent\nXLSX is echoed back as `false`.\n",
                "oneOf": [
                  {
                    "type": "boolean",
                    "enum": [
                      false
                    ]
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "localized_column_names": {
                        "type": "boolean",
                        "default": false,
                        "description": "If true, column headers use localized display names\ninstead of api-names.\n"
                      },
                      "hierarchy": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "column",
                          "\u003e",
                          "/"
                        ],
                        "default": null,
                        "description": "How object hierarchy/path is rendered in a column.\nEmpty string is treated as unset; other values are\nrejected.\n"
                      },
                      "include_changelog": {
                        "description": "Either a boolean (legacy) or an object enabling the\nchangelog.\n",
                        "oneOf": [
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "object",
                            "additionalProperties": false,
                            "properties": {
                              "with_user": {
                                "type": "boolean",
                                "default": false,
                                "description": "If true, include the changelog user column."
                              }
                            }
                          }
                        ]
                      },
                      "include_thumbnail": {
                        "type": "boolean",
                        "default": false,
                        "description": "If true, embed object thumbnails in the XLSX output."
                      }
                    }
                  }
                ]
              },
              "json": {
                "type": "boolean",
                "description": "Whether to include a JSON representation."
              },
              "json_one_file_per_object": {
                "type": "boolean",
                "description": "If true, every object becomes its own JSON file; otherwise a\nsingle JSON containing all objects.\n"
              },
              "merge_linked_objects": {
                "type": "string",
                "enum": [
                  "none",
                  "in_main_search",
                  "not_in_main_search",
                  "not_in_main_search_unless_reverse",
                  "all"
                ],
                "description": "Controls whether (and how) objects linked from the main\nsearch result are pulled into the export.\n"
              },
              "merge_max_depth": {
                "type": "integer",
                "description": "Maximum recursion depth when following linked objects.\n"
              },
              "include_parents": {
                "type": "boolean",
                "description": "If true, include parent objects when an included object\nreferences a parent.\n"
              },
              "file_url_expire_days": {
                "type": "integer",
                "description": "Number of days the file URLs embedded in the export remain\nvalid. Defaults to a server-side setting.\n"
              },
              "produce_options": {
                "type": "object",
                "additionalProperties": true,
                "description": "Options for the export *producer*. Only the reserved key\n`plugin` is interpreted by fylr; every other key is passed\nthrough verbatim to the selected producer. `plugin` selects\nthe producer: a value containing a colon is resolved as\n`\u003cplugin-name\u003e:\u003ccallback-name\u003e` against the loaded plugins\n(callback type `export`); a value without a colon is an\ninternal producer name (`json`, `xml`, `csv`, `file`, `iiif`,\n`html`, `xlsx`). A non-string `plugin` is rejected.\n",
                "properties": {
                  "plugin": {
                    "type": "string",
                    "description": "Producer selector. `\u003cplugin\u003e:\u003ccallback\u003e` resolves a plugin\nexport callback; a colon-less value is an internal\nproducer name.\n"
                  }
                },
                "example": {
                  "plugin": "my-plugin:my_export"
                }
              },
              "all_languages": {
                "type": "boolean",
                "default": false,
                "description": "If true, export all configured languages for localized fields\ninstead of only the standard/requested languages.\n"
              },
              "file_metadata": {
                "type": "boolean",
                "default": false,
                "description": "If true, include file (asset) metadata in the export output."
              },
              "no_inheritance": {
                "type": "boolean",
                "default": false,
                "description": "If true, do not resolve inherited field values; exported\nobjects carry only their own field values.\n"
              },
              "batch_size": {
                "type": "integer",
                "format": "int32",
                "nullable": true,
                "minimum": 0,
                "maximum": 10000,
                "default": null,
                "description": "Number of objects processed per batch. `null` (or omitted)\nmeans no explicit batch size. When set it must be between 0\nand 10000 inclusive, otherwise the save is rejected.\n"
              },
              "flat": {
                "type": "boolean",
                "default": false,
                "description": "Flat-output flag."
              },
              "filename_original": {
                "type": "boolean",
                "default": false,
                "description": "If true, exported files keep their original filename. Mutually\nexclusive with `filename_template`.\n"
              },
              "filename_template": {
                "type": "string",
                "nullable": true,
                "default": null,
                "description": "Template used to build exported filenames. Mutually exclusive\nwith `filename_original`.\n"
              }
            }
          },
          "_date_created": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the export was created."
          },
          "_last_updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the export configuration was last updated."
          },
          "_last_run_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the most recent production run started."
          },
          "_last_relevant_object_count": {
            "type": "integer",
            "description": "Number of objects included in the most recent run that had at\nleast one change since the previous run.\n"
          },
          "_last_relevant_run_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time of the most recent run that actually produced output\n(vs. a run that found nothing new).\n"
          },
          "_next_run_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the next scheduled run is expected. Set by the\n`_schedules` entries.\n"
          },
          "_state": {
            "type": "string",
            "enum": [
              "new",
              "pending",
              "processing",
              "done",
              "done_with_warnings",
              "failed"
            ],
            "description": "Current export run state. `new` after create/update; `pending`\nonce a run is scheduled; `processing` while a run is active;\n`done` / `done_with_warnings` on success; `failed` on error or\nafter a stop.\n"
          },
          "_plugin_log": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Lines of plugin-emitted log output captured during the most\nrecent run. Cleared at the start of each run.\n"
          },
          "_files": {
            "type": "array",
            "description": "Produced artifact files of the most recent run. Hidden files are\nomitted from regular (non-plugin) API output.\n",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "path",
                "date_created"
              ],
              "properties": {
                "path": {
                  "type": "string",
                  "description": "URL-path-escaped relative path of the produced file inside\nthe export package.\n"
                },
                "size": {
                  "type": "integer",
                  "format": "int64",
                  "description": "File size in bytes. Omitted when the size is unknown (e.g.\nfiles produced on the fly); a missing `size` therefore means\n\"unknown\", distinct from a real 0.\n"
                },
                "date_created": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Creation timestamp (RFC3339)."
                }
              }
            }
          },
          "_log": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventApi"
            },
            "description": "Per-run event log — start/stop, validation failures, transport\nresults.\n"
          },
          "_transports": {
            "type": "array",
            "description": "Configured delivery transports and their per-transport result.\nRound-trips between request and response.\n",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "plugin",
                "options"
              ],
              "properties": {
                "plugin": {
                  "type": "string",
                  "description": "Transport selector. Empty string for an internal/download\ntransport, otherwise `\u003cplugin\u003e:\u003ccallback\u003e`.\n"
                },
                "options": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "Free-form transport options whose accepted keys depend on\nthe selected transport plugin. Secret values are hidden on\noutput; an absent options object is rendered as `{}`.\n"
                },
                "email": {
                  "type": "object",
                  "additionalProperties": false,
                  "description": "Email-delivery settings. Present only when a message or\nrecipients exist.\n",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Optional email body message."
                    },
                    "recipients": {
                      "type": "array",
                      "description": "User/group recipients.",
                      "items": {
                        "$ref": "#/components/schemas/WhoApi"
                      }
                    }
                  }
                },
                "external_url": {
                  "type": "string",
                  "description": "External download URL for the transport (set server-side)."
                },
                "uuid": {
                  "type": "string",
                  "description": "Transport UUID. Auto-assigned for pure download transports;\nmay also be supplied on input and is used to log in to the\nexport.\n"
                }
              }
            }
          },
          "_schedules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScheduleApi"
            },
            "description": "Schedules controlling automatic re-runs of the export. Same\nshape as `user.mail_schedule`.\n"
          }
        }
      },
      "PresetApi": {
        "type": "object",
        "description": "A **right preset** — a reusable bundle of ACL grants (and an optional\ntag filter) that can be applied to objects or collections. Presets\nlive per context (`object` or `collection`).\n",
        "required": [
          "_basetype",
          "right_preset"
        ],
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "right_preset"
            ],
            "description": "Fixed marker identifying this object as a right preset."
          },
          "right_preset": {
            "type": "object",
            "required": [
              "preset"
            ],
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64",
                "description": "Server-issued numeric id. Required for updates."
              },
              "_version": {
                "type": "integer",
                "format": "int64"
              },
              "_position": {
                "type": "integer",
                "description": "Display position. Lower positions render before higher ones\nin the preset picker.\n"
              },
              "displayname": {
                "$ref": "#/components/schemas/LocaValue"
              },
              "description": {
                "$ref": "#/components/schemas/LocaValue"
              },
              "preset": {
                "type": "object",
                "description": "The actual permission bundle this preset represents.",
                "properties": {
                  "default_expiration_hours": {
                    "type": "integer",
                    "format": "int64",
                    "description": "How many hours after the preset is applied the granted\nACL items expire. If null, grants are permanent until\nrevoked.\n"
                  },
                  "share_url": {
                    "type": "string",
                    "description": "Optional absolute base URL (`http`/`https`) used instead of\nthe server's own external URL when building collection share\nlinks (copy-link buttons and share notification emails) for\nshares that use this preset. The deep-link path is appended\nto it: a `share_url` of `https://media.example.com/awp`\nproduces links like\n`https://media.example.com/awp/collection/\u003cuuid\u003e?...`.\nOnly supported in context `collection`; sending it for an\n`object` preset is rejected with `400 Bad Request`. An empty\nstring clears the URL; if the field is omitted on update,\nthe stored value is kept.\n"
                  },
                  "rights": {
                    "type": "object",
                    "description": "The right items the preset grants. Keys are right names\n(`read`, `write`, `delete`, `acl`, ...); each value is\na RightItemApi (same per-right configuration shape used\ninside RightApi.rights).\n",
                    "additionalProperties": {
                      "$ref": "#/components/schemas/RightItemApi"
                    }
                  },
                  "tagfilter": {
                    "$ref": "#/components/schemas/TagfilterApi",
                    "description": "Optional tag-filter that restricts which objects this\npreset can apply to (e.g. only objects tagged\n`confidential`).\n"
                  }
                }
              }
            }
          },
          "_created_at": {
            "type": "string",
            "format": "date-time"
          },
          "_updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BackupApi": {
        "type": "object",
        "description": "A **backup** descriptor — a record of a single backup run produced by\n`PUT /api/v1/system/backup/new`.\n",
        "required": [
          "id",
          "created_at",
          "status"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "description": "Server-issued numeric id."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the backup was created."
          },
          "finished_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the backup completed. Null while the backup is still\nrunning.\n"
          },
          "create_user": {
            "$ref": "#/components/schemas/WhoApi",
            "description": "The user that triggered the backup. Omitted for backups\ntriggered by the scheduler.\n"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "done",
              "error"
            ],
            "description": "Current backup state — `running`, `done`, `error`.\n"
          },
          "stats": {
            "$ref": "#/components/schemas/BackupStatsApi",
            "description": "Stats captured at the end of the run — file size, MIME type\nand file name of the produced artifact.\n"
          },
          "opts": {
            "$ref": "#/components/schemas/BackupOptsApi",
            "description": "The options the backup was started with — format and whether\nthe event log was included.\n"
          },
          "log": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "msg": {
                  "type": "string"
                }
              },
              "required": [
                "created_at",
                "msg"
              ]
            },
            "description": "Per-run log lines emitted by the backup pipeline."
          }
        }
      },
      "LocationApi": {
        "type": "object",
        "description": "A **storage location** descriptor — an external bucket where fylr\nreads / writes files. Used by `/api/v1/system/location*` and\nsurfaced read-only on every file download via the\n`X-Fylr-Storage-Location` response header.\n",
        "required": [
          "id",
          "kind"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "description": "Server-issued numeric id. On create, must be set to the same\nvalue that appears in the URL `/system/location/{id}` (or\n`0` for `POST /system/location/new`).\n"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time the location was created."
          },
          "name": {
            "type": "string",
            "description": "Human-readable label.\n"
          },
          "kind": {
            "type": "string",
            "enum": [
              "file",
              "s3",
              "azure"
            ],
            "description": "Storage driver — `file` (local disk), `s3` (AWS / S3-compatible),\nor `azure` (Azure Blob Storage). Selects which `config` shape\n(`file` / `s3` / `azure`) is expected.\n"
          },
          "prefix": {
            "type": "string",
            "description": "Optional bucket prefix — every key written to the location is\nprepended with it. Usually ends in `/`.\n"
          },
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Driver-specific configuration. Secrets (access keys, account\npasswords, ...) are removed on read; they must be supplied\nagain on update.\n"
          },
          "allow_purge": {
            "type": "boolean",
            "description": "Whether `POST /api/v1/system/purgeall` may delete files from\nthis location. Disable to keep an archival location intact.\n"
          },
          "allow_redirect": {
            "type": "boolean",
            "description": "Whether file downloads from this location may use HTTP\n`Location:` redirects (for remote buckets with their own URL\nsigners).\n"
          },
          "read_only": {
            "type": "boolean",
            "description": "Whether this location accepts writes. If true, new files are\nsent to the next writable location and only reads come from\nhere.\n"
          },
          "status": {
            "type": "string",
            "enum": [
              "connected",
              "not accessible",
              "error",
              "closed"
            ],
            "description": "Read-only connection state — `connected`, `not accessible`,\n`error`, `closed`.\n"
          },
          "status_msg": {
            "type": "string",
            "description": "Read-only diagnostic message attached to a non-`connected`\n`status` — usually the underlying error from the driver.\n"
          }
        }
      },
      "TransitionApi": {
        "type": "object",
        "description": "A **workflow transition** descriptor — one rule in the\nadmin-managed transition set. `GET` / `POST /api/v1/transitions`\nread and replace this set; the rules themselves fire implicitly\nthrough the object pipeline (insert / update / delete / tag), not\nvia a separate call.\n",
        "example": {
          "type": "process",
          "operations": [
            "INSERT",
            "UPDATE"
          ],
          "sticky": false,
          "objecttype_ids": [
            1
          ],
          "actions": [
            {
              "type": "set_tags",
              "info": {
                "tags": [
                  {
                    "_id": 5,
                    "set": true
                  }
                ]
              }
            }
          ],
          "who": [
            {
              "_basetype": "user",
              "user": {
                "_id": 1
              }
            }
          ]
        },
        "required": [
          "type"
        ],
        "properties": {
          "_id": {
            "type": "integer",
            "format": "int64",
            "description": "Server-issued numeric id."
          },
          "type": {
            "type": "string",
            "enum": [
              "resolve",
              "reject",
              "exit_resolve",
              "exit_reject",
              "process"
            ],
            "description": "Transition kind. One of `resolve`, `reject`, `exit_resolve`,\n`exit_reject`, `process`. Any other value is rejected with a\n`ServerGeneric` error (HTTP 400).\n"
          },
          "operations": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INSERT",
                "UPDATE",
                "DELETE"
              ]
            },
            "description": "Object-pipeline operations the transition runs on. Each item is\none of `INSERT`, `UPDATE`, `DELETE` (uppercase). An empty array\nis allowed and disables the transition. Any other value is\nrejected with a `ServerGeneric` error (HTTP 400).\n\nDiffers from easydb 5: easydb 5 requires a non-empty array;\n**fylr** accepts an empty array (which disables the transition).\n"
          },
          "comment": {
            "type": "string",
            "description": "Admin-facing comment / note (not user-visible).\n\nDiffers from easydb 5: this field does not exist in easydb 5; it\nis a **fylr** addition.\n"
          },
          "confirm": {
            "$ref": "#/components/schemas/LocaValue",
            "description": "Confirmation prompt shown to the user before the transition\nexecutes. Optional — empty for transitions that do not require\nexplicit confirmation.\n"
          },
          "sticky": {
            "type": "boolean",
            "description": "Boolean flag stored on the transition and round-tripped\nverbatim by this endpoint.\n"
          },
          "who_not": {
            "type": "boolean",
            "description": "If true, the `who` list is interpreted as a deny-list instead\nof an allow-list — every user EXCEPT those in `who` can\ninvoke the transition.\n\nDiffers from easydb 5: this field does not exist in easydb 5; it\nis a **fylr** addition.\n"
          },
          "objecttype_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Object types the transition applies to. Empty means it\napplies to every object type.\n"
          },
          "tagfilter:before": {
            "$ref": "#/components/schemas/TagfilterApi",
            "description": "Tagfilter the target object must satisfy BEFORE the transition\nruns. The optional `changed` slot — set only on transitions —\nidentifies the tags whose addition / removal should *trigger*\nthe transition.\n"
          },
          "tagfilter:after": {
            "$ref": "#/components/schemas/TagfilterApi",
            "description": "Tagfilter the target object will satisfy AFTER the transition\nruns (used by the engine to enforce the post-condition).\n"
          },
          "actions": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "type",
                "info"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "description": "Action discriminator. Built-in values: `set_tags`,\n`change_owner`, `email`, `webhook`. Any other string is\nrouted to a plugin action runner (e.g.\n`fylr_example:set_comment`).\n\nDiffers from easydb 5: `change_owner` is a **fylr**\naddition (easydb 5's built-in actions are only `set_tags`,\n`email`, and `webhook`, plus plugin actions).\n"
                },
                "info": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "Type-specific parameters. Shapes for built-in types:\n`set_tags` -\u003e `{\"tags\":[{\"_id\":\u003ctag id\u003e,\"set\":true|false}]}`;\n`change_owner` -\u003e `{\"owner\":\u003cWhoApi\u003e}`;\n`email` -\u003e `{\"subject\":\u003cLocaValue\u003e,\"message\":\u003cLocaValue\u003e,\"batchable\":\u003cbool\u003e,\"recipients\":[\u003cWhoApi\u003e]}`;\n`webhook` -\u003e `{\"name\":\u003cconfigured webhook name\u003e,\"callback\":\"pre_save\"|\"after_commit_async\"}`\n(callback defaults to `after_commit_async`).\nPlugin action types carry whatever the plugin declares.\n"
                }
              }
            },
            "description": "Ordered list of actions the transition performs. Each action is\n`{type, info}`; the parameters live under `info`, not at the top\nlevel.\n"
          },
          "who": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WhoApi"
            },
            "description": "Users / groups that may invoke this transition (or, if\n`who_not` is true, the deny-list). Same shape as the `who`\nslot on RightApi grants.\n"
          }
        }
      },
      "SchemaApi": {
        "type": "object",
        "description": "A fylr **datamodel** snapshot at a specific version — the JSON-Schema\nview that `/api/db` and `/api/search` validate against.\n\nThis is the shape `GET /api/v1/schema/user/{version}` returns when\nthe `format` query parameter is unset (or any value other than `svg`\n/ `png`).\n",
        "required": [
          "version",
          "type",
          "tables"
        ],
        "properties": {
          "version": {
            "type": "integer",
            "format": "int64",
            "description": "The datamodel version this snapshot represents. Every datamodel\nrecord carries a version — HEAD's version equals the version a\nfuture commit would produce. To distinguish HEAD from a committed\nsnapshot, check `committed_at` (null on HEAD).\n"
          },
          "based_on_version": {
            "type": "integer",
            "format": "int64",
            "description": "The committed datamodel version this snapshot derives from. For\na committed version, equals `version - 1`. For `HEAD`, the last\ncommitted version this working copy was forked off.\n"
          },
          "based_on_base_version": {
            "type": "integer",
            "format": "int64",
            "description": "The base-version (pre-customisation) the snapshot derives from.\nUsed by upgrades to track the upstream baseline separately from\nper-instance edits.\n"
          },
          "max_table_id": {
            "type": "integer",
            "format": "int64",
            "description": "Highest `table_id` used in this snapshot. New tables added in a\nsubsequent edit start at `max_table_id + 1`.\n"
          },
          "max_column_id": {
            "type": "integer",
            "format": "int64",
            "description": "Highest column id used in this snapshot. New columns added in a\nsubsequent edit start at `max_column_id + 1`.\n"
          },
          "type": {
            "type": "string",
            "enum": [
              "user"
            ],
            "description": "Always `user` — the user-defined datamodel. (fylr also has a\n`system` datamodel; that one is not exposed through /schema.)\n"
          },
          "tables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SchemaTableApi"
            },
            "description": "The objecttypes (tables) in this datamodel. Each entry is a\n`SchemaTableApi`. Which entries are present is\n**instance-dependent** — it reflects the customer's actual\nobjecttypes (`picture`, `event`, `person`, ...).\n"
          }
        }
      },
      "SchemaTableApi": {
        "type": "object",
        "description": "A single **objecttype** (table) within a datamodel snapshot. Each\nentry in `SchemaApi.tables` is one of these.\n",
        "required": [
          "name",
          "table_id",
          "columns"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Stable, machine-readable name of the objecttype (used as the\n`{objecttype}` path parameter on `/api/v1/db/{objecttype}` and\nas the key on `/api/v1/objecttype/{id}`).\n"
          },
          "table_id": {
            "type": "integer",
            "format": "int64",
            "description": "Server-issued numeric id, unique within the datamodel. Survives\nrenames of the objecttype.\n"
          },
          "pool_link": {
            "type": "boolean",
            "description": "If true, objects of this type live inside a pool — their `_pool`\nproperty identifies the containing pool. If false, objects are\nnot pool-scoped (instance-global).\n"
          },
          "owned_by": {
            "$ref": "#/components/schemas/OwnedByApi",
            "description": "When present, this table is a nested table — records ship\nembedded inside top-level objects of the objecttype the\ndescriptor's `other_table_id` points at, and have no\nindependent ACL or owner. Absent on regular top-level\nobjecttypes.\n"
          },
          "acl_table": {
            "type": "boolean",
            "description": "If true, objects of this type carry their own `_acl` and\nrespect per-object ACL grants. If false, ACL inheritance from\nthe parent pool / collection applies.\n"
          },
          "has_tags": {
            "type": "boolean",
            "description": "If true, objects of this type accept `_tags` (tag references).\nThe available tags come from `/api/v1/tags`.\n"
          },
          "is_hierarchical": {
            "type": "boolean",
            "description": "If true, this objecttype forms a **single-parent** tree —\neach object can have at most one parent via `_id_parent`.\nMutually exclusive with `polyhierarchical`.\n"
          },
          "polyhierarchical": {
            "type": "boolean",
            "description": "If true, this objecttype forms a **DAG** — each object can\nhave any number of parents, exposed through the\n`_object_parents` system column. Mutually exclusive with\n`is_hierarchical`; also incompatible with `acl_table: true`\n(the datamodel validator rejects both combinations).\n"
          },
          "in_main_search": {
            "type": "boolean",
            "description": "If true, objects of this type are indexed into the main search\nindex and surface in `/api/v1/search` results by default.\n"
          },
          "comment": {
            "type": "string",
            "description": "Admin-facing comment — not user-visible."
          },
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ColumnApi"
            },
            "description": "Ordered list of columns. The order matters for default rendering\nin masks that don't explicitly reorder.\n"
          },
          "foreign_keys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ForeignKeyApi"
            },
            "description": "Foreign-key declarations on this table — references to other\nobjecttypes' records used to look up linked data.\n"
          },
          "unique_keys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UniqueKeyApi"
            },
            "description": "Unique-key constraints. Violations surface as\n`DatabaseUniqueKeyViolation` on `POST /api/v1/db/{objecttype}`.\n"
          },
          "bidirectional": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BidirectionalApi"
            },
            "description": "Bidirectional-link declarations — pairs of columns on different\nobjecttypes that mirror each other (writing the link on one side\nautomatically materialises the reverse link on the other).\n"
          }
        }
      },
      "ObjecttypeApi": {
        "type": "object",
        "description": "An **objecttype** descriptor — fylr's per-record-type configuration\nlayered on top of the datamodel definition: per-objecttype default\nmasks, exposure flags (frontend menus, collections, facets), ACL\nrules, tags, transitions, mask / column filters, asset filename\npolicy, watermark and janitor (cleanup) policy.\n\nReturned by `/api/v1/objecttype` and `/api/v1/objecttype/{id}`. The\nsame shape is accepted as the request body of `POST /api/v1/objecttype`\n(only the fields the requester is allowed to mutate are honoured).\n",
        "required": [
          "_basetype",
          "objecttype"
        ],
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "objecttype"
            ],
            "description": "Fixed marker identifying this object as an objecttype."
          },
          "objecttype": {
            "type": "object",
            "description": "The mutable objecttype data.",
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64",
                "description": "Server-issued numeric id of the objecttype. Required for\nupdates. Stable across renames of `name`.\n"
              },
              "_version": {
                "type": "integer",
                "format": "int64",
                "description": "Version; increment on each update."
              },
              "name": {
                "type": "string",
                "description": "Stable, machine-readable name (used as the `{objecttype}`\npath parameter on `/api/v1/db/{objecttype}`).\n"
              },
              "contact": {
                "type": "object",
                "nullable": true,
                "description": "Vestigial field. Not backed by any objecttype storage: it is\nalways returned as `null` and ignored on `POST`. (Unlike the\npool's `contact`, this is never resolved to a user / group.)\n"
              },
              "mapping_image_export": {
                "description": "Reference to the image-export mapping: either the integer id\nof a mapping, or the string `\"none\"`. Returned as `\"none\"`\nwhen no mapping is set; any other value is rejected.\n"
              },
              "mapping_image_import": {
                "description": "Reference to the image-import mapping: either the integer id\nof a mapping, or the string `\"none\"`. Returned as `\"none\"`\nwhen no mapping is set; any other value is rejected.\n"
              },
              "mapping_image_import_recipe_configs": {
                "$ref": "#/components/schemas/RecipeConfigs",
                "description": "Per-recipe configuration for the image-import mapping. Only\naccepted when `mapping_image_import` names a mapping (not\n`\"none\"`).\n"
              },
              "mapping_dc_export": {
                "description": "Reference to the Dublin Core export mapping: either the\ninteger id of a mapping, or the string `\"none\"`. Returned as\n`\"none\"` when no mapping is set; any other value is rejected.\n"
              },
              "show_in_collections": {
                "type": "boolean",
                "description": "Whether objects of this type can be linked into collections.\n"
              },
              "show_in_facet_grouping": {
                "type": "boolean",
                "description": "Whether the type appears as a top-level facet in the search\nUI's grouping.\n"
              },
              "show_in_main_menu_with_icon": {
                "type": "string",
                "description": "Icon name to show next to the objecttype entry in the\nfront-end main menu. Empty / null suppresses the entry.\n"
              },
              "empty_placeholder_icon": {
                "type": "string",
                "description": "Icon shown in the detail view when an object of this type\nhas no file attached.\n"
              },
              "standard_numbering": {
                "type": "string",
                "description": "Legacy field. Present in the response (always empty) and\naccepted in a `POST` body, but the value is ignored — it is\nnever stored or applied.\n"
              },
              "description": {
                "$ref": "#/components/schemas/LocaValue"
              },
              "custom_data": {
                "type": "object",
                "additionalProperties": true,
                "description": "Custom-data values attached to the objecttype itself (per\nthe datamodel's objecttype customisation).\n"
              },
              "watermark": {
                "$ref": "#/components/schemas/WatermarkApi",
                "description": "Watermark configuration applied to image variants produced\nfrom objects of this type.\n"
              },
              "caption": {
                "$ref": "#/components/schemas/CaptionByFieldApi",
                "description": "Per-field caption configuration burned into image variants\nproduced for objects of this type. Keys are field names on\nthe objecttype.\n"
              },
              "janitor_policy": {
                "$ref": "#/components/schemas/JanitorPolicyApi",
                "description": "Per-objecttype retention / purge policy enforced by the\njanitor. Same shape as the pool-level janitor policy.\n"
              }
            }
          },
          "_standard_masks": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true,
            "description": "Ordered list of mask ids to prefer when rendering objects of\nthis type. The first entry is the default mask. `null` (rather\nthan an empty array) signals \"no preference defined\" — the\ndatamodel's standard mask is then used.\n"
          },
          "_export_asset_filenames": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/LocaValue"
            },
            "description": "Per-field filename templates used when exporting assets. Each key\nis the full api name of a field on this objecttype that is either\na files column or a link to an objecttype that has files; an\nunknown field is rejected with `UnknownField`, a field of any\nother type with `UnsupportedFieldType`. The value is the\nlocalised filename template (placeholders come from\n`_filename_replacements`). Empty templates are dropped on save.\n"
          },
          "_acl": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RightApi"
            },
            "description": "ACL grants on this objecttype — typically the\n`objecttype.read` / `objecttype.write` / `objecttype.delete`\nrights.\n"
          },
          "_private_transitions": {
            "type": "boolean",
            "description": "If true, transitions configured directly on this objecttype do\nnot inherit transitions from the parent pool / global.\n"
          },
          "_transitions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransitionApi"
            },
            "description": "Workflow transitions exposed on this objecttype."
          },
          "_private_tags": {
            "type": "boolean",
            "description": "If true, the tag set configured on this objecttype shadows the\ninherited tags (does not merge with them).\n"
          },
          "_tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            },
            "description": "Per-objecttype tag definitions."
          },
          "_compiled_tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            },
            "description": "Effective tag set — the merge of this objecttype's tags with\nthe inherited tags from pool / global.\n"
          },
          "_maskfilters": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "tagfilter": {
                  "$ref": "#/components/schemas/TagfilterApi"
                }
              }
            },
            "description": "Per-mask tag-filter overrides, keyed by mask id. A mask's\n`tagfilter` restricts which objects the mask is offered for.\n"
          },
          "_columnfilters": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Per-column visibility filters — used to hide individual fields\nfrom users that lack a matching tag / right.\n"
          },
          "_filename_replacements": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "readOnly": true,
            "description": "Read-only helper, computed server-side. Keys are the full api\nnames of the objecttype's files fields; each value is the list of\nplaceholder tokens (e.g. `%_asset.original_filename%`,\n`%\u003cfield\u003e%`) available for that field's `_export_asset_filenames`\ntemplate. Output only — ignored if sent in a `POST` body.\n"
          }
        }
      },
      "XmlMappingProfile": {
        "type": "object",
        "description": "A **profile** for XML / Exiftool / Dublin Core import or export — the\ntemplate from which concrete `XmlMappingApi` mappings are derived.\nProfiles are loaded from `xmlmapping/\u003cprofile\u003e.yml` files in the\nbase config (and from plugins that contribute their own).\n\nReturned by `GET /api/v1/xmlmapping/profile/{profile}` and embedded\nin each entry of `GET /api/v1/xmlmapping/list` (with its concrete\nmappings appended under `mappings`).\n",
        "required": [
          "profile",
          "profile_type"
        ],
        "properties": {
          "profile": {
            "type": "string",
            "description": "Stable profile name as stored — this is the file's `profile:`\nvalue and includes the source file extension, e.g. `dc.yml`.\nThis exact string is the `{profile}` path parameter of\n`GET /xmlmapping/profile/{profile}` and the `XmlMappingApi.profile`\nvalue of mappings built from it.\n"
          },
          "displayname": {
            "$ref": "#/components/schemas/LocaValue"
          },
          "profile_type": {
            "type": "object",
            "description": "Capability flags. Determine which targets this profile can be\nbound to when creating a concrete mapping.\n",
            "properties": {
              "xml_export": {
                "type": "boolean",
                "description": "Profile can drive an XML export."
              },
              "exiftool_export": {
                "type": "boolean",
                "description": "Profile can drive an Exiftool-based metadata export."
              },
              "exiftool_export_omit_empty": {
                "type": "boolean",
                "description": "When set, exiftool export skips mapping fields with no\nvalue and no source — instead of emitting an empty\n`-Tag=` wipe. Inherited from the profile to new mappings.\n"
              },
              "exiftool_import": {
                "type": "boolean",
                "description": "Profile can drive an Exiftool-based metadata import."
              },
              "dc_export": {
                "type": "boolean",
                "description": "Profile can drive a Dublin Core export."
              },
              "plugins_import": {
                "type": "boolean",
                "description": "When set, plugin-contributed import mapping definitions are\nautomatically merged into the profile on read.\n"
              }
            }
          },
          "xml_base": {
            "type": "string",
            "description": "Base XML namespace URL that the resulting XML documents anchor\nthemselves to. Mostly relevant for XML export.\n"
          },
          "tabs": {
            "type": "array",
            "description": "The profile's field layout, grouped into tabs (each tab is one\npage in the front-end editor).\n",
            "items": {
              "type": "object",
              "properties": {
                "tab": {
                  "type": "string",
                  "description": "Stable tab id."
                },
                "text": {
                  "$ref": "#/components/schemas/LocaValue"
                },
                "custom": {
                  "type": "boolean",
                  "description": "If true, the front end lets the user add custom fields\ninside this tab.\n"
                },
                "fields": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/XmlMappingProfileField"
                  }
                }
              }
            }
          },
          "_compiled_recipes": {
            "type": "object",
            "additionalProperties": true,
            "description": "Per-recipe compiled state — the recipes this profile uses at\nruntime, keyed by recipe name. Read-only; managed by the\nmapping pipeline.\n"
          },
          "mappings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "format": "int64",
                  "description": "The concrete mapping's id."
                },
                "displayname": {
                  "$ref": "#/components/schemas/LocaValue"
                },
                "_recipes_required": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Recipe names the mapping needs at runtime. The instance\nmust have all of them registered (via base config or a\nplugin) for the mapping to be usable.\n"
                }
              }
            },
            "description": "Concrete mappings built from this profile. Always present\n(possibly an empty array) on both `GET /xmlmapping/list` and\n`GET /xmlmapping/profile/{profile}` — the list handler sets a\nnon-nil `mappings` slice for every profile and the per-profile\nhandler returns that same profile object unchanged.\n"
          }
        }
      },
      "XmlMappingProfileField": {
        "type": "object",
        "description": "A single field inside an XML-mapping profile tab. Describes the\nXML / Exiftool / JSON source / target plus the fylr-side target\nfields and the import strategy.\n",
        "properties": {
          "_id": {
            "type": "string",
            "description": "Stable field id (a slug derived from the profile file). Used\nto correlate `XmlMappingApi.fields` entries with their profile\ndefinition.\n"
          },
          "name": {
            "type": "string",
            "description": "Human-facing field name (the front-end label).\n"
          },
          "strategy_import": {
            "type": "string",
            "description": "How the field combines incoming values on import — e.g.\n`replace`, `append`, `merge`, `skip_if_present`.\n"
          },
          "type": {
            "type": "string",
            "enum": [
              "Output",
              "Splitter",
              "Input",
              "Hidden"
            ],
            "description": "`Output` — exported; `Input` — imported only; `Splitter` — drives\nsub-field decomposition; `Hidden` — internal helper, not exposed\nin the editor.\n"
          },
          "text": {
            "description": "Display text for the editor. Accepts either a plain string or a\n`LocaValue` (`{\u003clang\u003e: \u003ctext\u003e}`) for localised labels.\n",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "$ref": "#/components/schemas/LocaValue"
              }
            ]
          },
          "xml": {
            "type": "string",
            "description": "Free-form XML hint shown next to the field in the editor (for\nreviewers who want to see the target XPath / element).\n"
          },
          "xml_export": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/XmlMappingFieldExport"
            },
            "description": "Per-source XML-export rules — XPath / attribute / value\nformatters applied when this field's value is written out.\n"
          },
          "xml_import": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/XmlMappingFieldImport"
            },
            "description": "Per-source XML-import rules — the XPath / attribute / value\nreaders applied when an incoming document is parsed.\n"
          },
          "json_import": {
            "type": "string",
            "description": "JSON pointer used to read the field's value during a JSON\nimport.\n"
          },
          "json_import_type": {
            "type": "string",
            "description": "Column type the value should be coerced into when imported\n(e.g. `text`, `number`, `date`).\n"
          },
          "easydb": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/XmlMappingFieldEasydb"
            },
            "description": "Fylr-side target fields the value flows into. Each entry\nidentifies a column path and any per-target transformation.\n"
          },
          "custom": {
            "type": "boolean",
            "description": "Marker set on fields the user added (not declared in the\nprofile YAML). Custom fields can be edited and deleted from\nthe front end.\n"
          },
          "x": {
            "type": "integer",
            "description": "Optional grid column position used by the front-end layout\neditor.\n"
          },
          "y": {
            "type": "integer",
            "description": "Optional grid row position used by the front-end layout\neditor.\n"
          },
          "recipe_name": {
            "type": "string",
            "description": "Recipe this field's compilation depends on. Set by the loader\nwhen the profile references a recipe.\n"
          }
        }
      },
      "XmlMappingApi": {
        "type": "object",
        "description": "A concrete **XML mapping** — pairs a profile with a target\nobjecttype, the field bindings and any recipe configuration the\nmapping needs at runtime.\n\nUsed as the request body of `PUT /api/v1/xmlmapping/mapping` and\n`POST /api/v1/xmlmapping/mapping/{mapping}`, and as the response\nbody of `GET /api/v1/xmlmapping/mapping/{mapping}`.\n",
        "required": [
          "profile"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "description": "Server-issued numeric id. Empty / 0 on create; required on\nupdate.\n"
          },
          "idTable": {
            "type": "integer",
            "format": "int64",
            "description": "Objecttype id this mapping targets. Required for every mapping\nexcept global / cross-objecttype ones.\n"
          },
          "displayname": {
            "$ref": "#/components/schemas/LocaValue"
          },
          "profile": {
            "type": "string",
            "description": "Profile name (`xmlmapping.Profile.profile`) the mapping is\nbuilt from. Must match an existing profile registered with the\ninstance.\n"
          },
          "profile_type": {
            "type": "object",
            "description": "Snapshot of the profile's capability flags at the time the\nmapping was created. Used to surface stale-mapping warnings\nwhen the underlying profile is updated.\n",
            "properties": {
              "xml_export": {
                "type": "boolean",
                "description": "Read and persisted from the request body."
              },
              "exiftool_export": {
                "type": "boolean",
                "description": "Read and persisted from the request body."
              },
              "exiftool_export_omit_empty": {
                "type": "boolean",
                "description": "Read and persisted from the request body."
              },
              "exiftool_import": {
                "type": "boolean",
                "description": "Read and persisted from the request body."
              },
              "dc_export": {
                "type": "boolean",
                "description": "Read-only on a mapping: returned in responses (it reflects the\nmapping's stored flag) but ignored in `PUT`/`POST` request\nbodies — the request decoder does not copy it.\n"
              },
              "plugins_import": {
                "type": "boolean",
                "description": "Profile-level flag only (see `XmlMappingProfile.profile_type`).\nIt is not persisted on a mapping — neither read from the\nrequest body nor written to the response — and is listed here\nonly because the request/response object shares the\n`profile_type` shape.\n"
              }
            }
          },
          "xml_base": {
            "type": "string",
            "description": "Override of the profile's `xml_base` namespace anchor for this\nmapping. Optional.\n"
          },
          "fields": {
            "type": "array",
            "description": "Per-field bindings — one entry per profile field this mapping\nconfigures. Order is meaningful for export.\n",
            "items": {
              "$ref": "#/components/schemas/XmlMappingProfileField"
            }
          },
          "limited_extensions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Optional whitelist of file extensions (e.g. `tif`, `jpg`)\nthis mapping should be offered for. Empty means no restriction.\n"
          },
          "recipe_configs": {
            "type": "object",
            "additionalProperties": true,
            "description": "Per-recipe configuration applied when this mapping runs.\nKeys are recipe names; values are the recipe's configuration\nobject.\n"
          },
          "custom": {
            "type": "boolean",
            "description": "Read-only marker set when the mapping was created by a user\n(vs. loaded from a config file). Custom mappings are editable\nand deletable through the API; config-loaded ones aren't.\n"
          }
        }
      },
      "MaskApi": {
        "type": "object",
        "x-recursion": true,
        "description": "A **mask** descriptor — projects an objecttype to a subset of fields,\nwith per-field rendering / editability metadata. Masks are the unit\nthrough which the front-end renders forms and detail views.\n\nReturned inside the `masks` array of the `MaskSchemaApi` wrapper by\n`GET /api/v1/mask/{version}` and `GET /api/v1/mask/{version}/{mask}`.\n\nMasks can recursively contain sub-masks via `fields[].mask`; the\n`x-recursion: true` marker tells the renderer to stop at one level\nof nesting.\n",
        "properties": {
          "name": {
            "type": "string",
            "description": "Stable mask name. The special name `_all_fields` returns the\nobjecttype's complete field set (available to any authenticated\nuser).\n"
          },
          "mask_id": {
            "type": "integer",
            "format": "int64",
            "description": "Server-issued numeric id; stable across renames."
          },
          "table_id": {
            "type": "integer",
            "format": "int64",
            "description": "Numeric id of the objecttype this mask belongs to (matches\n`SchemaTableApi.table_id`).\n"
          },
          "table_name_hint": {
            "type": "string",
            "description": "Convenience copy of the objecttype name — saves clients an\nobjecttype lookup when rendering breadcrumbs.\n"
          },
          "is_preferred": {
            "type": "boolean",
            "description": "Whether this mask is one of the pool / objecttype's preferred\nmasks. Omitted on sub-mask entries (nested in another mask).\n"
          },
          "hide_in_detail": {
            "type": "boolean",
            "description": "Suppress this mask from the front-end detail-view picker.\n"
          },
          "hide_in_editor": {
            "type": "boolean",
            "description": "Suppress this mask from the front-end editor picker.\n"
          },
          "hide_in_print_dialog": {
            "type": "boolean",
            "description": "Suppress this mask from the print / export dialog.\n"
          },
          "standard_numbering": {
            "type": "string",
            "description": "Numbering scheme applied to objects produced through this mask\n(overrides the objecttype-level setting when non-empty).\n"
          },
          "require_comment": {
            "type": "string",
            "description": "Optional rule that forces the user to add a comment when saving\nthrough this mask. Empty / omitted means no requirement.\nRecognised values include `always`, `on_change`, ...\n"
          },
          "comment": {
            "type": "string",
            "description": "Admin-facing free-text comment on the mask itself. Not shown\nto end users.\n"
          },
          "system_fields": {
            "$ref": "#/components/schemas/SystemFieldApi",
            "description": "Per-mask system-field overrides (visibility, label, default).\nOnly present on top-level masks; omitted on sub-masks.\n"
          },
          "fields": {
            "type": "array",
            "description": "The ordered list of fields included in this mask. Each entry\nidentifies the underlying column plus per-field mask\nconfiguration (required, read-only, default, embedded sub-mask).\n",
            "items": {
              "$ref": "#/components/schemas/FieldApi"
            }
          },
          "name_localized": {
            "$ref": "#/components/schemas/LocaValue"
          },
          "table_name_localized": {
            "$ref": "#/components/schemas/LocaValue"
          },
          "custom_settings": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Free-form key/value pairs for plugin / theme consumers. Keys\nand values are strings; semantics are owned by the consumer.\n"
          }
        }
      },
      "MaskSchemaApi": {
        "type": "object",
        "description": "The full **mask schema** document — the wrapper returned by\n`GET /mask/{version}` and `GET /mask/{version}/{mask}` and the body\nthat `POST /mask/HEAD` expects and returns: schema-level metadata\n(`type`, `version`, `based_on_schema_version`, `max_mask_id`) plus\nthe array of masks. The single-mask GET returns the same wrapper\nwith `masks` filtered to the one requested mask.\n\nThis is what the working datamodel writes to and reads from; once\nthe masks are saved into HEAD, they only become visible to other\nreaders after a separate `POST /api/v1/schema/commit`.\n",
        "required": [
          "type",
          "masks"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "user"
            ],
            "description": "Always `\"user\"` — distinguishes mask-schema documents from\ndatamodel-schema documents on the same code path.\n"
          },
          "version": {
            "type": "integer",
            "description": "Schema-format marker, always `1` on output. Not consumed on\ninput to `POST /mask/HEAD`.\n"
          },
          "based_on_schema_version": {
            "type": "integer",
            "description": "On output, the datamodel version this mask set was read from\n(the server sets it from the loaded datamodel). On input to\n`POST /mask/HEAD` it is decoded but not consumed: the write\nalways applies to the current HEAD.\n"
          },
          "max_mask_id": {
            "type": "integer",
            "format": "int64",
            "description": "Highest `mask_id` server has issued so far. New masks the\nclient adds without `mask_id` are assigned ids starting at\n`max_mask_id + 1`.\n"
          },
          "masks": {
            "type": "array",
            "description": "The full set of masks the datamodel HEAD should hold after\nthe write. Sending fewer masks than HEAD currently has\ndeletes the missing ones.\n",
            "items": {
              "$ref": "#/components/schemas/MaskApi"
            }
          }
        },
        "example": {
          "type": "user",
          "version": 1,
          "based_on_schema_version": 1,
          "max_mask_id": 0,
          "masks": [
            {
              "name": "_all_fields",
              "table_id": 1,
              "table_name_hint": "object",
              "is_preferred": false,
              "hide_in_detail": false,
              "hide_in_editor": false,
              "hide_in_print_dialog": false,
              "standard_numbering": "",
              "comment": "",
              "system_fields": {
                "object_id": {
                  "output": {
                    "mode": "show"
                  },
                  "edit": {
                    "mode": "show"
                  }
                },
                "tags": {
                  "output": {
                    "mode": "off"
                  },
                  "edit": {
                    "mode": "off"
                  }
                },
                "owner": {
                  "output": {
                    "mode": "show"
                  },
                  "edit": {
                    "mode": "edit"
                  }
                },
                "publish": {
                  "output": {
                    "mode": "show"
                  }
                }
              },
              "fields": [
                {
                  "kind": "field",
                  "column_id": 1,
                  "column_name_hint": "date",
                  "edit": {
                    "mode": "edit"
                  },
                  "output": {
                    "detail": true,
                    "text": true,
                    "table": true,
                    "standard": {
                      "format": "comma"
                    },
                    "standard_eas": {}
                  },
                  "search": {
                    "expert": true,
                    "fulltext": true,
                    "facet": true,
                    "nested": false
                  },
                  "custom_settings": {},
                  "inheritance": null
                },
                {
                  "kind": "field",
                  "column_id": 2,
                  "column_name_hint": "text",
                  "edit": {
                    "mode": "edit"
                  },
                  "output": {
                    "detail": true,
                    "text": true,
                    "table": true,
                    "standard": {
                      "format": "comma",
                      "order": 1
                    },
                    "standard_eas": {}
                  },
                  "search": {
                    "expert": true,
                    "fulltext": true,
                    "facet": false,
                    "nested": false
                  },
                  "custom_settings": {},
                  "inheritance": null
                },
                {
                  "kind": "field",
                  "column_id": 3,
                  "column_name_hint": "pic",
                  "edit": {
                    "mode": "edit"
                  },
                  "output": {
                    "detail": true,
                    "text": true,
                    "table": true,
                    "standard": {
                      "format": "comma"
                    },
                    "standard_eas": {
                      "order": 1
                    }
                  },
                  "search": {
                    "expert": true,
                    "fulltext": true,
                    "facet": false,
                    "nested": false
                  },
                  "custom_settings": {},
                  "inheritance": null
                }
              ]
            }
          ]
        }
      },
      "FieldApi": {
        "type": "object",
        "x-recursion": true,
        "description": "One **field** entry inside a mask — the per-mask configuration for\none column (or for an embedded sub-mask). Carries the underlying\ncolumn's id and name hint, link / reverse-link metadata, the mask's\nper-field edit / output / search behaviour, plus any nested sort\nand inheritance settings.\n",
        "properties": {
          "kind": {
            "type": "string",
            "description": "Field kind — currently `column` (a regular field referencing one\ncolumn) or `link` (a navigation field that exposes a linked\nobjecttype's record through this mask). Empty / omitted when\nthe entry represents an inline placeholder.\n"
          },
          "type": {
            "type": "string",
            "description": "The underlying column type (`text`, `select`, `link`, `nested`,\n`reverse`, ...). Copy of the column's `Type` for client\nconvenience.\n"
          },
          "options": {
            "type": "string",
            "description": "Free-form options string (typically per-column type-specific\nflags). Empty / omitted for fields without options.\n"
          },
          "column_id": {
            "type": "integer",
            "format": "int64",
            "description": "Numeric id of the column this field points at. Stable across\nrenames.\n"
          },
          "column_name_hint": {
            "type": "string",
            "description": "Current column name — provided as a convenience so clients don't\nneed a separate column lookup when rendering. May be stale if\nthe column was just renamed.\n"
          },
          "is_hierarchical": {
            "type": "boolean",
            "description": "Whether the underlying column is a hierarchical link (`_id_parent`-style).\n"
          },
          "other_table_id": {
            "type": "integer",
            "format": "int64",
            "description": "For link / nested / reverse columns — the linked objecttype's\n`table_id`.\n"
          },
          "other_table_name_hint": {
            "type": "string"
          },
          "other_column_id": {
            "type": "integer",
            "format": "int64",
            "description": "For reverse-link columns — the linked-back column's id on the\nother table.\n"
          },
          "other_column_name_hint": {
            "type": "string"
          },
          "hierarchical_mask_hint": {
            "type": "boolean",
            "description": "Whether the linked record should be rendered through its\nhierarchical mask (vs. the standard mask).\n"
          },
          "inline": {
            "type": "string",
            "description": "Inline rendering directive (front-end-defined). Controls whether\nthe linked record is shown inline next to the field or in a\nseparate panel.\n"
          },
          "mask_id": {
            "description": "The mask the linked record should be rendered through. Either an\ninteger mask id, the string `\"preferred\"`, or `\"standard\"`.\n",
            "oneOf": [
              {
                "type": "integer",
                "format": "int64"
              },
              {
                "type": "string",
                "enum": [
                  "preferred",
                  "standard"
                ]
              }
            ]
          },
          "edit": {
            "type": "object",
            "description": "Per-mask edit-mode settings for this field.",
            "properties": {
              "mode": {
                "type": "string",
                "description": "Edit mode — `edit`, `show` (read-only), `off` (hidden in\neditor), `requireConfirm`, ...\n"
              },
              "append_only": {
                "type": "boolean",
                "description": "For collection-valued fields — entries can be added but\nexisting entries cannot be removed through this mask.\n"
              },
              "remove_only": {
                "type": "boolean",
                "description": "For collection-valued fields — existing entries can be\nremoved but no new entries may be added through this mask.\n"
              }
            }
          },
          "output": {
            "type": "object",
            "description": "Where and how this field is rendered in output contexts.",
            "properties": {
              "detail": {
                "type": "boolean",
                "description": "Show in detail view."
              },
              "text": {
                "type": "boolean",
                "description": "Include in plain-text rendering (search snippets, exports)."
              },
              "table": {
                "type": "boolean",
                "description": "Include in tabular rendering."
              },
              "standard": {
                "type": "object",
                "description": "Field's contribution to the object's `_standard` rendering —\nthe short label fylr produces for an object in pickers and\nbreadcrumbs.\n",
                "properties": {
                  "design": {
                    "type": "string"
                  },
                  "format": {
                    "type": "string"
                  },
                  "format_inner": {
                    "type": "string"
                  },
                  "order": {
                    "type": "integer"
                  },
                  "stop_if_set": {
                    "type": "boolean"
                  }
                }
              },
              "standard_eas": {
                "type": "object",
                "description": "Field's `_standard` ordering for the EAS-rendered string.",
                "properties": {
                  "order": {
                    "type": "integer"
                  }
                }
              },
              "standard_geo": {
                "type": "object",
                "description": "Field's `_standard` ordering for the geo-rendered string. Geometries copied into `_standard` are simplified (Ramer-Douglas-Peucker) to at most `fylr.geo.standardMaxVertices` vertices per shape; the field value itself keeps full precision.",
                "properties": {
                  "order": {
                    "type": "integer"
                  }
                }
              }
            }
          },
          "search": {
            "type": "object",
            "description": "Per-field search behaviour.",
            "properties": {
              "expert": {
                "type": "boolean",
                "description": "Available in the expert search."
              },
              "fulltext": {
                "type": "boolean",
                "description": "Indexed for full-text search."
              },
              "facet": {
                "type": "boolean",
                "description": "Available as a search facet."
              },
              "nested": {
                "type": "boolean",
                "description": "Nested search — only meaningful on fields whose underlying\ncolumn is `nested` / `reverse`.\n"
              }
            }
          },
          "custom_settings": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Plugin / theme-consumed key/value pairs. Keys and values are\nstrings; semantics are owned by the consumer.\n"
          },
          "nested_sort": {
            "type": "array",
            "description": "For nested-link fields — sort directives applied to the linked\nrecords when this field is displayed.\n",
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string",
                  "description": "Column api-name to sort by."
                },
                "order": {
                  "type": "string",
                  "enum": [
                    "asc",
                    "desc"
                  ]
                }
              }
            }
          },
          "nested_standard_first_only": {
            "type": "boolean",
            "description": "For nested-link fields — when true, only the first nested record\ncontributes to the object's `_standard` rendering.\n"
          },
          "inheritance": {
            "type": "object",
            "description": "For fields backed by inheritable columns — controls whether the\nfield is inherited from parent records.\n",
            "properties": {
              "inherit": {
                "type": "boolean"
              },
              "show_in_detail": {
                "type": "boolean"
              }
            }
          },
          "mask": {
            "$ref": "#/components/schemas/MaskApi",
            "description": "Embedded sub-mask used to render the linked record (for `link`\n/ `nested` / `reverse` fields). Recursion is broken at render\ntime via MaskApi's `x-recursion: true` marker (when set on the\nschema).\n"
          },
          "column": {
            "$ref": "#/components/schemas/ColumnApi",
            "description": "The underlying column descriptor, surfaced for clients that\ndon't have the full datamodel in hand.\n"
          },
          "full_name": {
            "type": "string",
            "description": "Fully-qualified field path — `\u003ctable\u003e.\u003ccolumn\u003e` for top-level\nfields, deeper for nested sub-mask fields.\n"
          }
        }
      },
      "ColumnApi": {
        "type": "object",
        "description": "A **column** — one field definition on an objecttype. Carries the\ncolumn's identity (`name`, `column_id`, `type`), nullability,\nvalidation rules, and link metadata (for `link` / `nested` /\n`reverse` columns).\n",
        "properties": {
          "kind": {
            "type": "string",
            "description": "Column kind — typically empty for user columns, `system` for\nfylr-managed columns (`_id`, `_pool`, `_owner`, ...).\n"
          },
          "name": {
            "type": "string",
            "description": "Stable, machine-readable column name. Used as the JSON key on\nobjects of this type.\n"
          },
          "type": {
            "type": "string",
            "description": "Column data type. Recognised types include `text`, `text-l10n`,\n`select`, `link`, `nested`, `reverse`, `reverse_hierarchical`,\n`date`, `daterange`, `number`, `boolean`, `tags`, `eas`, plus\n`custom:*` types contributed by plugins. Enabled plugins\nsurface their custom types in the rights catalog\n(`GET /api/v1/right`); the datamodel rejects unknown types\non save with `code: UnknownColumnType`.\n"
          },
          "not_null": {
            "type": "boolean",
            "description": "Whether the column requires a non-null value on every write.\n"
          },
          "column_id": {
            "type": "integer",
            "format": "int64",
            "description": "Server-issued numeric id; stable across renames.\n"
          },
          "reverse_edit": {
            "type": "boolean",
            "description": "For `reverse` columns — whether the column can be edited from\nthis side (vs. read-only mirroring of the link).\n"
          },
          "is_hierarchical": {
            "type": "boolean",
            "description": "For self-referential `link` columns — true if the column forms\na hierarchy (`_id_parent`).\n"
          },
          "check": {
            "type": "string",
            "description": "Stored CHECK constraint expression (SQL fragment). Empty when\nno constraint is set.\n"
          },
          "check_regexp": {
            "type": "string",
            "description": "Regex the value must match (for `text` columns).\n"
          },
          "check_regexp_flags": {
            "type": "string",
            "description": "Optional regex flags (`i` for case-insensitive, ...).\n"
          },
          "check_range_lower": {
            "description": "Lower bound of an allowed value range."
          },
          "check_range_upper": {
            "description": "Upper bound of an allowed value range."
          },
          "check_range_lower_open": {
            "description": "When set, the lower bound is exclusive (`\u003e`). Otherwise inclusive\n(`\u003e=`).\n"
          },
          "check_range_upper_open": {
            "description": "When set, the upper bound is exclusive (`\u003c`). Otherwise inclusive\n(`\u003c=`).\n"
          },
          "check_range_not_empty": {
            "type": "boolean",
            "description": "For `daterange` / numeric range columns — whether an empty range\nis rejected.\n"
          },
          "length_min": {
            "type": "integer",
            "description": "Minimum string length (for `text` columns)."
          },
          "length_max": {
            "type": "integer",
            "description": "Maximum string length (for `text` columns)."
          },
          "other_table_id": {
            "type": "integer",
            "format": "int64",
            "description": "For link / nested / reverse columns — the linked objecttype's\n`table_id`.\n"
          },
          "other_table_name_hint": {
            "type": "string",
            "description": "Convenience copy of the linked objecttype's name."
          },
          "other_column_id": {
            "type": "integer",
            "format": "int64",
            "description": "For `reverse` columns — the linked-back column's id on the\nother table.\n"
          },
          "other_column_name_hint": {
            "type": "string",
            "description": "Convenience copy of the linked-back column's name."
          },
          "bidirectional_reverse": {
            "type": "boolean",
            "description": "For columns participating in a bidirectional link — true if\nthis column is the reverse half of the pair (writes to it\nmirror through the forward half).\n"
          },
          "custom_settings": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Plugin / theme-consumed key/value pairs on the column. Keys and\nvalues are strings; semantics are owned by the consumer.\n"
          },
          "name_localized": {
            "$ref": "#/components/schemas/LocaValue",
            "description": "Localised display name for the column. Shown wherever the\nfront-end surfaces the column label.\n"
          }
        }
      },
      "OwnedByApi": {
        "type": "object",
        "description": "Marks the table as a **nested table** of the objecttype identified\nby `other_table_id`. Nested rows have no independent identity:\nthey ship as embedded values inside the top-level objects of the\nobjecttype `other_table_id` points at, have no `_acl` of their\nown and don't carry an owner. On the wire they surface under\n`_nested:\u003ctable-name\u003e` (or `_reverse_nested:\u003ctable-name\u003e`) on the\ntop-level object.\n\nThe name `owned_by` is historical. fylr is an easydb 6 Go\nrewrite that targets the easydb 5 API contract; in easydb 5 every\nnested table was a real DB table with an owning-table foreign\nkey. fylr keeps the nested values inside the top-level object's\nJSON instead, but the descriptor's name (and its `other_table_id`\nslot) stuck.\n\nConstraint: a nested table cannot declare `reverse_link` columns\n— the datamodel validator rejects that on save.\n",
        "required": [
          "other_table_id"
        ],
        "properties": {
          "other_table_id": {
            "type": "integer",
            "format": "int64",
            "description": "`table_id` of the objecttype this table is a nested table of.\nMust point at a table that exists in the same datamodel\nsnapshot.\n"
          },
          "other_table_name_hint": {
            "type": "string",
            "description": "Convenience copy of that objecttype's name — saves clients a\nseparate lookup when rendering. May be stale if the\nobjecttype was just renamed.\n"
          }
        }
      },
      "ForeignKeyApi": {
        "type": "object",
        "description": "A **foreign-key** declaration on a table. Documents the DB-level\nreference between this table's `columns` and the `referenced_table`\nprimary key, plus the cascade behaviour fylr applies on delete /\nupdate.\n",
        "required": [
          "columns",
          "referenced_table"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Database-level constraint name. Server-issued; clients should\ntreat it as opaque.\n"
          },
          "on_delete": {
            "type": "string",
            "description": "Cascade action when a referenced row is deleted. Standard SQL\nvalues: `CASCADE`, `RESTRICT`, `SET NULL`, `SET DEFAULT`,\n`NO ACTION`.\n"
          },
          "on_update": {
            "type": "string",
            "description": "Cascade action when a referenced row's primary key is updated.\nSame values as `on_delete`.\n"
          },
          "columns": {
            "type": "array",
            "description": "The column(s) on **this** table that participate in the foreign\nkey. Multi-column keys reference a composite key on the other\nside, in the same order.\n",
            "items": {
              "type": "object",
              "required": [
                "column_id"
              ],
              "properties": {
                "column_id": {
                  "type": "integer",
                  "format": "int64",
                  "description": "Numeric id of the column on this table."
                },
                "column_name_hint": {
                  "type": "string",
                  "description": "Convenience copy of the column's current name."
                }
              }
            }
          },
          "referenced_table": {
            "type": "object",
            "required": [
              "table_id",
              "columns"
            ],
            "description": "The table this key points at and the columns on its side.",
            "properties": {
              "table_id": {
                "type": "integer",
                "format": "int64",
                "description": "`table_id` of the referenced table.\n"
              },
              "name_hint": {
                "type": "string",
                "description": "Convenience copy of the referenced table's name."
              },
              "columns": {
                "type": "array",
                "description": "The referenced table's columns this FK targets — paired\npositionally with this table's `columns` array.\n",
                "items": {
                  "type": "object",
                  "properties": {
                    "auto_column_primary_key": {
                      "type": "boolean",
                      "description": "True when the referenced column is the referenced\ntable's auto-managed primary key (`_id`).\n"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "UniqueKeyApi": {
        "type": "object",
        "description": "A **unique-key** constraint on a table. Violations surface as\n`DatabaseUniqueKeyViolation` on `POST /api/v1/db/{objecttype}`.\n",
        "required": [
          "columns"
        ],
        "properties": {
          "group": {
            "type": "string",
            "description": "Constraint-group label (`a` / `b` / `c`). Lets multiple unique\nconstraints be authored side-by-side on the same table — same\ngroup label means they are alternatives, not all required.\n"
          },
          "columns": {
            "type": "array",
            "description": "The column(s) that together must be unique. A multi-column key\nrequires the combination to be unique, not each column\nindividually.\n",
            "items": {
              "type": "object",
              "properties": {
                "auto_column_parent": {
                  "type": "boolean",
                  "description": "True when the column is the auto-managed `_id_parent`\n(hierarchical link).\n"
                },
                "auto_column_uplink": {
                  "type": "boolean",
                  "description": "True when the column is the auto-managed uplink column\nfor a hierarchical parent-child relationship.\n"
                },
                "column_id": {
                  "type": "integer",
                  "format": "int64",
                  "description": "Numeric id of the column."
                },
                "column_name_hint": {
                  "type": "string",
                  "description": "Convenience copy of the column's current name."
                }
              }
            }
          }
        }
      },
      "BidirectionalApi": {
        "type": "object",
        "description": "A **bidirectional link** declaration — a pair of columns on two\ndifferent objecttypes that mirror each other. Writing the link on\none side automatically materialises the reverse link on the other;\nreading either side returns the same connection.\n",
        "required": [
          "columns"
        ],
        "properties": {
          "columns": {
            "type": "array",
            "description": "The two columns participating in the bidirectional link — the\nforward column on this table and the reverse column on the\nother (`bidirectional_reverse: true` on the other side's\nColumnApi).\n",
            "items": {
              "type": "object",
              "properties": {
                "auto_column_uplink": {
                  "type": "boolean",
                  "description": "True when the column is the auto-managed uplink column.\n"
                },
                "column_id": {
                  "type": "integer",
                  "format": "int64"
                },
                "column_name_hint": {
                  "type": "string",
                  "description": "Convenience copy of the column's current name."
                }
              }
            }
          }
        }
      },
      "LookupByReference": {
        "type": "object",
        "description": "Reference-based lookup descriptor — used on `lookup:_id` (or\n`lookup:_id_parent`) slots throughout the API. Lets clients\naddress an existing user / group / pool by its stable\n`reference` string instead of by numeric `_id`. The lookup must\nresolve to exactly one record; zero or multiple matches cause\nthe enclosing write to fail with `LookupNotFound` / `LookupNotUnique`.\n",
        "required": [
          "reference"
        ],
        "properties": {
          "reference": {
            "type": "string",
            "description": "The target record's `reference` string. Must match a stored\nreference on the addressed basetype exactly.\n"
          }
        }
      },
      "GeneratedRightsApi": {
        "type": "object",
        "description": "Read-only **generated rights** — the effective per-right\nconfiguration the requesting session holds on the resource that\ncarries the field. Returned by fylr inside many top-level\nresponses (objects, pools, groups, users, ...) so the front-end\ndoesn't have to recompute the ACL.\n\nKeyed by right name (one of the values from the rights catalog\nat `GET /api/v1/right`). Each value mirrors the same per-right\nconfiguration shape used inside `RightApi.rights` —\n`RightItemApi`.\n",
        "additionalProperties": {
          "$ref": "#/components/schemas/RightItemApi"
        }
      },
      "SystemRightsApi": {
        "type": "object",
        "description": "**System rights** granted to a principal (a group, a user, …) —\nthe instance-wide permissions the principal holds. The map is\nkeyed by right name (matches the entries in the `system` context\nof `GET /api/v1/right`); each value is a map of right-parameter\nname to that parameter's value.\n\nParameter value types are right-specific — the inner map carries\nwhatever shape the right's parameter declares (`bool`, `string`,\n`string-list`, ...). For a fully-typed view of which parameters\neach right accepts, consult the rights catalog.\n",
        "additionalProperties": {
          "type": "object",
          "description": "Per-right parameter assignments. Keys are parameter names; value\ntype matches the parameter's declared type in the rights catalog.\n",
          "additionalProperties": true
        },
        "example": {
          "system.user": {
            "read": true
          },
          "system.api.event": {
            "get": true
          },
          "system.api.publish": {
            "post": true,
            "get": true
          }
        }
      },
      "AutomaticAuthApi": {
        "type": "object",
        "description": "**Automatic-auth** descriptor — when set on a group, marks the\ngroup as one whose members can be granted a short-lived session\nthrough fylr's automatic-auth flow (action-code / email-link).\nCarries the auth method that issued the binding and a timestamp.\n",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Auth method that granted the automatic-auth binding. One of\n`easydb`, `anonymous`, `collection`, `email`, `action_code`,\n`auto` (and any auth method a plugin contributes).\n"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "When the binding was issued. Set server-side."
          }
        }
      },
      "AuthMethodGroupMapsApi": {
        "type": "object",
        "description": "**Auth-method group mappings** — rules that map external auth\nproviders (SSO, LDAP) and fylr's built-in system groups onto this\ngroup. Used so signed-in users from those identity sources are\nautomatically assigned to the group.\n\nEach entry is an array of rules. A rule succeeds when its `method`\n/ `value` test against the incoming auth subject holds. The\n`system` array only supports `method: \"eq\"` (other methods are\nrejected on save).\n",
        "properties": {
          "sso": {
            "type": "array",
            "description": "Rules matched against SSO subjects.",
            "items": {
              "$ref": "#/components/schemas/AuthGroupRuleApi"
            }
          },
          "ldap": {
            "type": "array",
            "description": "Rules matched against LDAP groups.",
            "items": {
              "$ref": "#/components/schemas/AuthGroupRuleApi"
            }
          },
          "system": {
            "type": "array",
            "description": "Rules matched against fylr's built-in system groups. Only\n`method: \"eq\"` is accepted; `value` must be the reference of\nan existing system group.\n",
            "items": {
              "$ref": "#/components/schemas/AuthGroupRuleApi"
            }
          }
        }
      },
      "AuthGroupRuleApi": {
        "type": "object",
        "description": "One rule inside an `_auth_method_group_maps.\u003csso|ldap|system\u003e`\narray. The rule's `method` says how to compare the incoming\nsubject against `value`; if it matches, the user is assigned to\nthe group.\n",
        "required": [
          "method",
          "value"
        ],
        "properties": {
          "method": {
            "type": "string",
            "description": "Comparison method. `eq` is supported everywhere; LDAP and SSO\ncontexts may also accept other comparison methods (regex /\nglob, depending on configuration). The `system` array only\naccepts `eq`.\n"
          },
          "value": {
            "type": "string",
            "description": "The string the rule matches against. For `system` rules, the\nreference of an existing system group; otherwise the value the\nexternal provider supplies (LDAP group DN, SSO claim value, ...).\n"
          }
        }
      },
      "GroupPseudoApi": {
        "type": "object",
        "description": "**Pseudonymization** template for a group. When a user account\nbelonging to this group is deleted, fylr replaces the user's\nidentifying fields with the strings configured here so that\nevent log entries and ACL grants remain attributable to \"some\nuser from this group\" without leaking the original identity.\n",
        "properties": {
          "user": {
            "type": "object",
            "description": "Pseudonymised replacements for the user's identifying fields.\nEmpty / unset uses the per-instance defaults.\n",
            "properties": {
              "login": {
                "type": "string",
                "description": "Pseudonymised login name."
              },
              "first_name": {
                "type": "string",
                "description": "Pseudonymised first name."
              },
              "last_name": {
                "type": "string",
                "description": "Pseudonymised last name."
              },
              "displayname": {
                "type": "string",
                "description": "Pseudonymised display name."
              },
              "additional_info": {
                "type": "string",
                "description": "Pseudonymised additional-info text."
              },
              "_emails": {
                "type": "string",
                "description": "Pseudonymised email — note the leading underscore in the\nJSON key.\n"
              }
            }
          }
        }
      },
      "ScheduleApi": {
        "type": "object",
        "description": "A **schedule** — selector of when a recurring action should run.\nUsed for the user's mail-notification schedule (`mail_schedule`)\nand elsewhere fylr lets users pick a recurrence in calendar terms\nrather than as a cron expression.\n\nAll fields are arrays; emptier means \"match any value\" for that\nfield. The schedule fires whenever the wall clock in `timezone`\nsatisfies every non-empty constraint.\n",
        "properties": {
          "days_of_month": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 31
            },
            "description": "Days of the month the schedule may fire on."
          },
          "weekdays": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "mon",
                "tue",
                "wed",
                "thu",
                "fri",
                "sat",
                "sun"
              ]
            },
            "description": "Weekdays the schedule may fire on. Lowercase three-letter\nabbreviations.\n"
          },
          "hours": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0,
              "maximum": 23
            },
            "description": "Hours of the day (in `timezone`)."
          },
          "minutes": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0,
              "maximum": 59
            },
            "description": "Minutes of the hour."
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone identifier (`Europe/Berlin`, `UTC`, ...). When\nomitted, the instance default timezone is used.\n"
          }
        }
      },
      "UserCollectionPinCodeApi": {
        "type": "object",
        "description": "A pin code the user holds for a pin-protected collection. Set by\nthe user when they unlock the collection for the first time;\nre-verified on each subsequent access.\n",
        "required": [
          "collection_id",
          "pin_code"
        ],
        "properties": {
          "collection_id": {
            "type": "integer",
            "format": "int64",
            "description": "`_id` of the collection the pin applies to. Must be a\npin-protected collection (`pin_required: true`).\n"
          },
          "pin_code": {
            "type": "string",
            "description": "The pin code as the user entered it. Stored hashed\nserver-side; the cleartext value is only present here on the\nwrite path. Reads return the same shape with the cleartext\nomitted when the requester is not the user themselves.\n"
          }
        }
      },
      "LocaleApi": {
        "type": "object",
        "description": "Locale metadata — number formatting and calendar text the front\nend uses to render localised values. Derived from CLDR for the\nuser's `frontend_language` (and per `database_locales` entry, for\neach language the user is allowed to edit data in).\n",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name of the locale in its own language (`Deutsch`,\n`English (United States)`, ...).\n"
          },
          "numbers": {
            "type": "object",
            "description": "Number-formatting separators.",
            "properties": {
              "decimal": {
                "type": "string",
                "description": "Decimal separator (`\",\"` in `de-DE`, `\".\"` in `en-US`).\n"
              },
              "grouping": {
                "type": "string",
                "description": "Grouping (thousands) separator (`\".\"` in `de-DE`,\n`\",\"` in `en-US`).\n"
              }
            }
          },
          "calendar": {
            "type": "object",
            "description": "Calendar text and date-format patterns (CLDR-derived).",
            "properties": {
              "bc": {
                "type": "string",
                "description": "Era marker before common era (e.g. `v. Chr.`)."
              },
              "ad": {
                "type": "string",
                "description": "Era marker (e.g. `n. Chr.`)."
              },
              "year": {
                "type": "string",
                "description": "Format pattern for a bare year."
              },
              "year_month": {
                "type": "string",
                "description": "Format pattern for a year-month value (`MMMM y`)."
              },
              "date": {
                "type": "string",
                "description": "Date format pattern (`dd.MM.yyyy`)."
              },
              "date_time": {
                "type": "string",
                "description": "Date+time format pattern."
              },
              "date_time_sec": {
                "type": "string",
                "description": "Date+time+seconds format pattern."
              },
              "date_time_sec_tz": {
                "type": "string",
                "description": "Date+time+seconds+timezone format pattern."
              }
            }
          }
        }
      },
      "SessionAuthenticationMethodApi": {
        "type": "object",
        "description": "One authentication method the instance exposes (or the method the\ncurrent session was established with).\n",
        "required": [
          "method"
        ],
        "properties": {
          "method": {
            "type": "string",
            "description": "The auth method identifier. Recognised values include `easydb`,\n`email`, `collection`, `action_code`, `auto`, `anonymous`, plus\nany method a plugin contributes.\n"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "When the session was authenticated through this method (only\nset on `authenticated`, not in the `authentication_methods`\ncatalog).\n"
          },
          "client_id": {
            "type": "string",
            "description": "Identifier of the client that drove the authentication (e.g.\nthe browser UUID). Empty for server-driven sessions.\n"
          }
        }
      },
      "WatermarkApi": {
        "type": "object",
        "description": "**Watermark** configuration applied to image variants produced by\nfylr's asset pipeline for objects in a given scope (a pool or an\nobjecttype). The watermark image is fetched through `image` (a\nfull file descriptor); the placement / appearance parameters\nfollow the ImageMagick conventions.\n",
        "properties": {
          "image": {
            "$ref": "#/components/schemas/file",
            "description": "File descriptor of the watermark image. Setting `image: null`\n(or omitting it) clears the watermark for this scope.\n"
          },
          "gravity": {
            "type": "string",
            "enum": [
              "nw",
              "n",
              "ne",
              "w",
              "c",
              "e",
              "sw",
              "s",
              "se",
              ""
            ],
            "description": "Anchor point on the produced image where the watermark is\nplaced, given as a short compass code. On save the API accepts\nexactly these values; any other value is rejected with\n`watermark.gravity \"\u003cvalue\u003e\" not supported`. fylr maps them\ninternally to the corresponding ImageMagick gravity:\n\n  * `nw` → NorthWest, `n` → North, `ne` → NorthEast\n  * `w` → West, `c` → Center, `e` → East\n  * `sw` → SouthWest, `s` → South, `se` → SouthEast\n  * `\"\"` (empty) → no gravity (placement defaults / tiling)\n",
            "examples": [
              "se",
              "c"
            ]
          },
          "dissolve": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Opacity of the watermark, in percent (`0` = invisible,\n`100` = fully opaque). The 0–100 range is enforced when the\nrendition is produced, not validated on save.\n"
          },
          "size": {
            "type": "string",
            "description": "Target size of the watermark on the produced image. When the\nrendition is produced fylr accepts a positive pixel size\n(`200`), a percentage of the canvas's largest side (`30%`), a\nfixed `\u003cwidth\u003ex\u003cheight\u003e` (`200x100`), or `\u003cwidth\u003e%x\u003cheight\u003e%`.\nThe value is not validated on save.\n"
          },
          "tile": {
            "type": "boolean",
            "description": "When true, the watermark image tiles across the whole canvas\ninstead of being placed once at `gravity`.\n"
          }
        }
      },
      "BackupStatsApi": {
        "type": "object",
        "description": "Summary stats captured for one backup run — filesize and the\ncontent-type / filename the produced backup artifact carries.\n",
        "required": [
          "filesize",
          "mimetype",
          "filename"
        ],
        "properties": {
          "filesize": {
            "type": "integer",
            "format": "int64",
            "description": "Size of the produced backup file, in bytes."
          },
          "mimetype": {
            "type": "string",
            "description": "MIME type of the produced backup file. Depends on the chosen\n`opts.format` — typically `application/vnd.sqlite3; charset=binary`\nfor SQLite snapshots, `application/x-tar` for pg_dump archives.\n"
          },
          "filename": {
            "type": "string",
            "description": "File name fylr assigns to the artifact —\n`fylr-backup-\u003cformat\u003e-\u003cinstance\u003e-\u003cYYYY-MM-DD HH:MM\u003e.\u003cext\u003e`.\n"
          }
        }
      },
      "BackupOptsApi": {
        "type": "object",
        "description": "Options the backup was started with. Echoed back on read so\nclients can tell which format the produced artifact is in.\n",
        "required": [
          "format"
        ],
        "properties": {
          "format": {
            "type": "string",
            "description": "Backup format. The recognised values are configured per\ninstance and surface in `GET /api/v1/system/backup/list`;\ntypical values include `sqlite3_db` (single-file SQLite\nsnapshot) and `pg_dump` (PostgreSQL dump archive).\n"
          },
          "include_events": {
            "type": "boolean",
            "description": "When true, the event log is included in the backup. When\nfalse, only the datamodel and user data are dumped — useful\nfor migrating to a new instance without carrying the event\nhistory along.\n"
          }
        }
      },
      "CaptionApi": {
        "type": "object",
        "description": "Per-field **caption** configuration — used by the asset-rendering\npipeline to burn a text caption into image variants produced for\nan objecttype's records.\n",
        "properties": {
          "text": {
            "type": "string",
            "description": "Caption text template. Supports the same field-reference syntax\nas other fylr text templates (`\u003cno value\u003e` etc.).\n"
          },
          "size": {
            "type": "string",
            "description": "Caption font size. Either a positive pixel integer (`24`) or a\npercentage of the canvas height (`1`–`50` followed by `%`).\n",
            "examples": [
              "24",
              "5%"
            ]
          },
          "padding": {
            "type": "string",
            "description": "Padding around the caption, in pixels. `0` or higher; no\ndecimals, no leading zeros.\n",
            "examples": [
              "8",
              "0"
            ]
          },
          "multiline": {
            "type": "boolean",
            "description": "Allow the caption to wrap across multiple lines."
          },
          "overlay": {
            "type": "boolean",
            "description": "When true, the caption is drawn on top of the image; when\nfalse, it's appended below.\n"
          }
        }
      },
      "CaptionByFieldApi": {
        "type": "object",
        "description": "Per-field caption configuration map — keyed by the field name on\nthe objecttype whose record's caption should be rendered for the\nasset. Each entry is a CaptionApi.\n",
        "additionalProperties": {
          "$ref": "#/components/schemas/CaptionApi"
        }
      },
      "JanitorPolicyApi": {
        "type": "object",
        "description": "**Janitor policy** — controls automatic cleanup of historic file\nversions and soft-deleted objects under this scope (a pool or an\nobjecttype). Both blocks are independently optional; `null` means\nthe corresponding cleanup is disabled.\n",
        "properties": {
          "file_link_delete": {
            "type": "object",
            "description": "When set, the janitor removes historic file versions linked\nfrom this scope's objects according to either time-based or\ncount-based retention. Set both fields to `0` to keep nothing\nand clean up immediately.\n",
            "properties": {
              "keep_days_history_versions": {
                "type": "integer",
                "minimum": 0,
                "description": "Keep historic versions newer than this many days. `0`\nmeans \"do not keep by time at all\".\n"
              },
              "keep_count_history_versions": {
                "type": "integer",
                "minimum": 0,
                "description": "Keep at most this many historic versions per file. `0`\nmeans \"do not keep any historic versions\".\n"
              }
            }
          },
          "object_purge": {
            "type": "object",
            "description": "When set, the janitor permanently purges soft-deleted objects\nthis scope owns once they have been deleted for at least\n`min_deleted_days`.\n",
            "properties": {
              "min_deleted_days": {
                "type": "integer",
                "minimum": 0,
                "description": "Number of days an object must have been soft-deleted\nbefore the janitor purges it. `0` means \"purge\nimmediately on soft-delete\".\n"
              }
            }
          }
        }
      },
      "XmlMappingFieldExport": {
        "type": "object",
        "description": "One **XML-export rule** for a profile field. Targets an XML\nlocation (XPath / element / attribute) and the value-formatting\noptions the writer applies.\n\n`list` and `l10n` control how multiple values and languages are\nwritten. With neither flag a single value is written (the preferred\nlanguage of a multilingual source, joined with `; ` for a repeatable\nfield). Set together they produce a **localized list** — an\n`rdf:Bag` whose entries are `rdf:Alt` language alternatives — for\ncustom tags and for tags whose schema defines that shape (e.g.\n`XMP-plus:Custom1`). A built-in tag can only take the shapes its\nschema allows; the mapping editor offers the valid options per tag\n(see the `list`/`l10n` capability flags on `GET /xmlmapping/tags`).\n",
        "example": {
          "path": "XMP-dc:Subject",
          "list": true
        },
        "properties": {
          "path": {
            "type": "string",
            "description": "XPath / element path the field's value is written to. May\ninclude namespace prefixes declared on the parent profile.\n"
          },
          "list": {
            "type": "boolean",
            "description": "When true, the field's values are written as an unordered\nlist — an XMP `rdf:Bag` with one `rdf:li` element per value.\nFor a multilingual (l10n) source field the bag collects the\nvalues of **all** languages, not only the preferred one, and a\nnested or repeatable field contributes every entry. Use this\nwhen the target tag holds plain values without language\ninformation, for example `dc:subject`.\n"
          },
          "l10n": {
            "type": "boolean",
            "description": "When true, the field's value is written localized per language\nas an XMP language alternative — an `rdf:Alt` carrying one\n`rdf:li` with an `xml:lang` attribute per language plus an\n`x-default`. Internally the writer emits one element per\nlanguage using the Exiftool-style `\u003cpath\u003e-\u003clang\u003e` suffix\nconvention, which Exiftool combines into the lang-alt. Use this\nfor a multilingual target tag such as `dc:title`.\n"
          },
          "attributes": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Static XML attributes to add to the output element. Keys are\nattribute names; values are the literal attribute strings.\n"
          },
          "elements_js": {
            "type": "string",
            "description": "Optional JavaScript snippet used to post-process the output\nelement. Set by the loader; not serialised on profile YAML.\n"
          }
        }
      },
      "XmlMappingFieldImport": {
        "type": "object",
        "description": "One **XML-import rule** for a profile field. Tells the reader how\nto find the field's value in an incoming XML document.\n",
        "required": [
          "search"
        ],
        "properties": {
          "search": {
            "type": "string",
            "description": "XPath / element search expression the reader runs against the\nincoming document to extract this field's value.\n"
          },
          "l10n_prefix": {
            "type": "string",
            "description": "Compatibility shim for easydb 5 — the language prefix used by\nthe legacy importer. Not consumed by fylr; kept on the wire\nfor round-trips with easydb-5 profile files.\n"
          }
        }
      },
      "XmlMappingTag": {
        "type": "object",
        "description": "One entry of the metadata **tag catalog** (`GET /xmlmapping/tags`):\na tag exiftool understands, with the capability flags the mapping\neditor uses to offer only the value-shapes the tag supports.\n",
        "example": {
          "writable": true,
          "path": "XMP-plus:Custom1",
          "group": "XMP-plus",
          "description": {
            "de-DE": "Benutzerdefiniert 1",
            "en-US": "Custom 1"
          },
          "type": "lang-alt",
          "l10n": true,
          "list": true,
          "list_type": "Bag"
        },
        "properties": {
          "path": {
            "type": "string",
            "description": "Tag path as used in a mapping's `xml_export`/`xml_import` rules,\nin the form `\u003cgroup\u003e:\u003ctag\u003e` (e.g. `XMP-dc:Subject`).\n"
          },
          "group": {
            "type": "string",
            "description": "Tag group (exiftool family-1 group, e.g. `XMP-dc`, `IPTC`,\n`ExifIFD`). Also the key into the response's `xmlns` map.\n"
          },
          "description": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Localized display name of the tag, keyed by frontend language\n(e.g. `de-DE`). May be empty for tags exiftool ships without\ntranslations.\n"
          },
          "writable": {
            "type": "boolean",
            "description": "When true, exiftool can write the tag — only writable tags are\noffered for export mappings.\n"
          },
          "type": {
            "type": "string",
            "description": "The exiftool value type, e.g. `string`, `integer`, `lang-alt`,\nor `?` for tags without a declared type.\n"
          },
          "l10n": {
            "type": "boolean",
            "description": "When true, the tag is a localized **lang-alt** (`rdf:Alt` with\none value per language). Derived from `type` being `lang-alt`.\nOmitted when false.\n"
          },
          "list": {
            "type": "boolean",
            "description": "When true, the tag is a repeatable list (an XMP `rdf:Bag` or\n`rdf:Seq`). Together with `l10n` this classifies the tag's\ncontainer: scalar (neither), list, lang-alt, or list-of-lang-alt\n(both — e.g. `XMP-plus:Custom1`, a localized list). Omitted when\nfalse.\n"
          },
          "list_type": {
            "type": "string",
            "enum": [
              "Bag",
              "Seq"
            ],
            "description": "The concrete list container. Only present when `list` is true.\n"
          }
        }
      },
      "XmlMappingFieldEasydb": {
        "type": "object",
        "description": "One **fylr-side target** for an XML-mapping field. Identifies the\ncolumn the value should land in and the display text the editor\nshows next to it.\n",
        "properties": {
          "text": {
            "type": "string",
            "description": "Display text shown for this target in the editor."
          },
          "type": {
            "type": "string",
            "description": "Column type hint. Currently unused by the server but mapped\nthrough for client convenience.\n"
          },
          "field": {
            "type": "string",
            "description": "The fylr column path the value flows into. Same syntax as\ndatamodel column references — `\u003cobjecttype\u003e.\u003ccolumn\u003e` for\nregular fields, dotted for nested links.\n"
          }
        }
      },
      "RecipeConfigs": {
        "type": "object",
        "description": "Per-recipe configuration. This object is a map whose keys are **recipe\nnames** and whose values configure that recipe for the current operation\n(e.g. producing a version or running a metadata mapping).\n\nRecipe name format:\n  * Built-in / config cookbooks: `COOKBOOK-NAME:RECIPE-NAME`\n    (for example `imageconverter:browserthumbs`).\n  * Plugin-provided recipes: `PLUGIN-NAME:COOKBOOK-NAME:RECIPE-NAME`.\n\nThe `params` of each recipe are **recipe-specific**: the set of valid\nparameter keys, their value types, defaults, ranges and option lists are\ndefined by each recipe individually, not by this API schema. That is why\n`params` is documented as an open object (`additionalProperties: true`)\nrather than a fixed schema — a closed schema cannot describe every recipe,\nand the available recipes additionally depend on which plugins are\ninstalled.\n\nTo discover the parameters a recipe accepts on a running instance, use the\nrecipe listing endpoint:\n\n    GET /inspect/apidocs/recipes/\n\nIt lists every cookbook and recipe currently loaded (including\nplugin-provided ones) together with each parameter's key, description and\ntype. Each value you send is validated against that recipe's parameter\ndefinition: unknown keys are rejected; a `string` param may be regex-\nconstrained; an `int` param is bounded by its `min`/`max`; a `select`\nparam must be one of the recipe's options; a `bool` param accepts a\nboolean or a string (`true`/`1`/`yes` mean true). Omitting a key (or\nsending `null`) applies the recipe's\ndefault; a parameter marked mandatory by the recipe must be supplied if it\nhas no default.\n",
        "additionalProperties": {
          "type": "object",
          "description": "Configuration for a single recipe, keyed in the parent map by the recipe\nname (see the parent description for the name format).\n",
          "properties": {
            "params": {
              "type": "object",
              "additionalProperties": true,
              "description": "Recipe-specific parameters as a map of parameter name to value.\n\nThe accepted keys and value types are defined by the recipe itself\nand are listed, per recipe, at `GET /inspect/apidocs/recipes/`.\nValidation rules applied per parameter, depending on the recipe's\ndeclared parameter type:\n  * string  — value must be a string; may be constrained by a regex.\n  * int     — value must be an integer (a numeric string is also\n              accepted); bounded by the parameter's `min`/`max`.\n  * select  — value must be a string equal to one of the parameter's\n              allowed options.\n  * bool    — value must be a boolean (a string is also accepted:\n              `true`/`1`/`yes` mean true, anything else false).\nAn absent key, or a `null` value, applies the recipe's default. A\nparameter the recipe marks as mandatory must be provided unless it has\na default. Keys not defined by the recipe are rejected.\n",
              "example": {
                "size": 600,
                "format": "png",
                "resize_mode": "max",
                "jpegquality": 80,
                "strip": true
              }
            }
          },
          "example": {
            "imageconverter:browserthumbs": {
              "params": {
                "size": 1200,
                "format": "webp",
                "resize_mode": "max"
              }
            },
            "imageconverter:preview_pool_watermark": {
              "params": {
                "size": 600,
                "format": "jpg"
              }
            }
          }
        }
      },
      "FileMetadata": {
        "type": "object",
        "description": "Free-form **file metadata** document — a map of metadata groups\nto per-group key/value bags.\n\nThe well-known group `_technical_metadata` carries the file's\nintrinsic properties (`width`, `height`, `dpi`, ...); other groups\ncarry whatever the configured metadata recipes produce (EXIF, IPTC,\nXMP, custom extractors). Group names beginning with `_` are\nreserved for fylr-managed groups; user-defined groups should use\nunprefixed names.\n\nEach group's value is a flat key/value bag whose values can be\nstrings, numbers, booleans, nested objects, or arrays — the type\nset per key is fixed by the producing recipe, not by fylr.\n",
        "properties": {
          "_technical_metadata": {
            "$ref": "#/components/schemas/technical_metadata"
          }
        },
        "additionalProperties": {
          "type": "object",
          "description": "A metadata group's key/value bag. Value types are recipe-defined.\n",
          "additionalProperties": true
        },
        "example": {
          "_technical_metadata": {
            "width": 4096,
            "height": 2048,
            "dpi": 144,
            "colorspace": "sRGB"
          },
          "exif": {
            "Make": "Canon",
            "Model": "EOS R5",
            "DateTimeOriginal": "2024:08:15 14:22:01"
          }
        }
      },
      "IiifImageInfo": {
        "type": "object",
        "description": "IIIF Image API 2.0 **image information** document — the standard\nreply to a `/info.json` request, defined by the [IIIF Image API\n2.0 specification](https://iiif.io/api/image/2.0/#image-information).\n\nfylr serves this document so any IIIF-aware client (Mirador,\nUniversal Viewer, OpenSeadragon, ...) can discover the image's\ndimensions, supported tile sizes and feature profile.\n",
        "required": [
          "@context",
          "@id",
          "protocol",
          "width",
          "height",
          "profile"
        ],
        "properties": {
          "@context": {
            "type": "string",
            "enum": [
              "http://iiif.io/api/image/2/context.json"
            ],
            "description": "JSON-LD context — always the IIIF Image API 2 URL."
          },
          "@id": {
            "type": "string",
            "format": "uri",
            "description": "The image's IIIF service URL — `/info.json` without the\n`/info.json` suffix.\n"
          },
          "protocol": {
            "type": "string",
            "enum": [
              "http://iiif.io/api/image"
            ],
            "description": "The IIIF protocol URI."
          },
          "width": {
            "type": "integer",
            "description": "The image's native width, in pixels."
          },
          "height": {
            "type": "integer",
            "description": "The image's native height, in pixels."
          },
          "profile": {
            "type": "array",
            "description": "Two-element array — the first item is a compliance-level URI\n(`http://iiif.io/api/image/2/level1.json`, `level2.json`, ...);\nthe second (optional) is a free-form object describing the\nadditional features the service supports beyond the level.\n",
            "items": {}
          },
          "tiles": {
            "type": "array",
            "description": "The tile geometries the service is willing to serve directly.\nClients use these to assemble deep-zoom mosaics without\ndownloading the full image.\n",
            "items": {
              "type": "object",
              "required": [
                "width",
                "scaleFactors"
              ],
              "properties": {
                "width": {
                  "type": "integer",
                  "description": "Tile width, in pixels (square unless `height` is given)."
                },
                "height": {
                  "type": "integer",
                  "description": "Tile height, in pixels. Defaults to `width`."
                },
                "scaleFactors": {
                  "type": "array",
                  "items": {
                    "type": "integer"
                  },
                  "description": "The downscaling factors the service can produce for these\ntiles (powers of two — `[1, 2, 4, 8, 16]`).\n"
                }
              }
            }
          },
          "sizes": {
            "type": "array",
            "description": "Pre-rendered fixed sizes the service can serve at full quality.\nClients should request from this list when they only need a\nwhole-image thumbnail.\n",
            "items": {
              "type": "object",
              "properties": {
                "width": {
                  "type": "integer"
                },
                "height": {
                  "type": "integer"
                }
              }
            }
          },
          "service": {
            "type": "array",
            "description": "Optional related services (auth, search, ...) advertised by\nthe image. Shape is service-dependent.\n",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "WhoApi": {
        "type": "object",
        "description": "**Who** — references a principal an ACL grant addresses (or names\nthe owner of an object). Exactly one of `_owner`, `_pool_contact`,\n`user`, `group` resolves; the rest are absent.\n",
        "properties": {
          "_basetype": {
            "type": "string",
            "enum": [
              "user",
              "group"
            ],
            "description": "The principal kind. Required for `user` / `group` references;\nabsent for `_owner` / `_pool_contact` synthetic principals.\n"
          },
          "_owner": {
            "type": "boolean",
            "description": "When `true`, the grant addresses *whoever currently owns* the\nresource (a synthetic principal that resolves per-object).\n"
          },
          "_pool_contact": {
            "type": "boolean",
            "description": "When `true`, the grant addresses the pool's configured contact\nuser. Only valid for grants on objects living in a pool.\n"
          },
          "user": {
            "type": "object",
            "description": "A specific user reference. Must carry either `_id` or\n`lookup:_id`. Other fields (`login`, `type`,\n`frontend_language`, `_generated_displayname`, ...) mirror the\nembedded user record; `additionalProperties: true` reflects\nthat on read fylr returns a UserDataApi snapshot which carries\nmany optional fields beyond `_id`.\n",
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64"
              },
              "lookup:_id": {
                "$ref": "#/components/schemas/LookupByReference",
                "description": "Reference-based lookup for the user. Resolved server-side.\n"
              },
              "_generated_displayname": {
                "type": "string",
                "description": "Read-only compiled displayname for the user (login,\nfirst/last name fallback chain).\n"
              }
            },
            "additionalProperties": true
          },
          "group": {
            "type": "object",
            "description": "A specific group reference. Must carry either `_id` or\n`lookup:_id`.\n",
            "properties": {
              "_id": {
                "type": "integer",
                "format": "int64"
              },
              "lookup:_id": {
                "$ref": "#/components/schemas/LookupByReference",
                "description": "Reference-based lookup for the group. Resolved server-side.\n"
              },
              "_generated_displayname": {
                "type": "string",
                "description": "Read-only compiled displayname for the group."
              }
            }
          }
        }
      },
      "RightApi": {
        "type": "object",
        "description": "An **ACL grant** — one entry of an `_acl` array. Combines a\nprincipal (`who`), a set of rights with per-right configuration\n(`rights`), an optional time window (`when`) and an optional tag\nfilter (`tagfilter`).\n",
        "required": [
          "who",
          "rights"
        ],
        "properties": {
          "_id": {
            "type": "integer",
            "format": "int64",
            "description": "Server-issued numeric id of the grant. Stable across updates;\nabsent when the grant is being created.\n"
          },
          "who": {
            "$ref": "#/components/schemas/WhoApi"
          },
          "sticky": {
            "type": "boolean",
            "description": "Sticky grants cannot be removed by lower-privileged updates —\na write that omits a sticky grant from the new ACL keeps it\nin place. Only `system.root` (or another grant marked sticky\nwith `_grantable`) can clear a sticky grant.\n"
          },
          "active": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the grant is currently effective. Defaults to `true`\nwhen omitted. Setting `false` suspends the grant without\ndeleting it. The capability map on the rights catalog says\nwhich contexts respect `active`.\n"
          },
          "_right_preset": {
            "type": "integer",
            "format": "int64",
            "description": "Id of the preset this grant was instantiated from (zero /\nomitted for hand-crafted grants).\n"
          },
          "when": {
            "type": "object",
            "description": "Optional time window outside of which the grant is treated\nas inactive. Both bounds are ISO 8601 timestamps; either or\nboth may be omitted.\n",
            "properties": {
              "from": {
                "type": "string",
                "format": "date-time",
                "description": "Grant takes effect at or after this timestamp."
              },
              "to": {
                "type": "string",
                "format": "date-time",
                "description": "Grant expires after this timestamp."
              }
            }
          },
          "rights": {
            "type": "object",
            "description": "Map of right name → per-right configuration. Keys are the\nright names from the rights catalog\n(`/api/v1/right`); each value is a `RightItemApi`.\n",
            "additionalProperties": {
              "$ref": "#/components/schemas/RightItemApi"
            }
          },
          "tagfilter": {
            "$ref": "#/components/schemas/TagfilterApi"
          },
          "send_email_notification": {
            "type": "object",
            "description": "Write-only — when set on creation, fylr sends a notification\nemail to the affected participants. Not part of the read\nshape.\n",
            "required": [
              "text"
            ],
            "properties": {
              "text": {
                "type": "string",
                "description": "Plain-text body of the notification email."
              }
            }
          }
        }
      },
      "RightItemApi": {
        "type": "object",
        "description": "One **right item** inside an ACL grant — the per-right\nconfiguration that scopes the right (which masks, objecttypes,\npools, file classes / extensions / versions it applies to) and\nwhether the grant is grantable downward.\n\nA `RightApi.rights` value is a map of right name → `RightItemApi`.\nUnset fields mean \"no constraint\" (apply to all); set to an empty\narray means \"no value matches\" (effectively disabled). The\nper-field constraint semantics depend on the right — see the\nrights catalog (`GET /api/v1/right`).\n",
        "properties": {
          "_grantable": {
            "type": "boolean",
            "description": "If true, the grantee may grant this right onward to others.\n"
          },
          "allow_update_and_remove": {
            "type": "boolean",
            "description": "For `update` / `remove` style rights, allow the grantee to\nboth modify and remove the resource (or only modify when\nfalse).\n"
          },
          "classes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Restrict to specific EAS classes (`image`, `document`, ...).\n`null` / absent means any class.\n"
          },
          "extensions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Restrict to specific file extensions. `null` / absent means\nany extension.\n"
          },
          "versions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Restrict to specific version names (`original`, `preview`,\n`thumbnail`, ...). `null` / absent means any version.\n"
          },
          "limit": {
            "type": "integer",
            "format": "int64",
            "description": "Upload size cap, in bytes (parsed from human-readable strings\nlike `\"10MB\"` on input). `0` means no cap.\n"
          },
          "mask_ids": {
            "type": "object",
            "description": "Per-objecttype mask restriction. Map of objecttype api id to\nan array of mask api ids (or the string `\"standard\"` for the\nobjecttype's standard mask).\n",
            "additionalProperties": {
              "type": "array",
              "items": {}
            }
          },
          "column_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Restrict to specific column api ids. Empty array matches all\ncolumns; absent means no constraint.\n"
          },
          "objecttype_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Restrict to specific objecttype api ids.\n"
          },
          "pool_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Restrict to specific pool ids. Empty array matches all pools;\nabsent means no constraint.\n"
          }
        }
      },
      "TagfilterApi": {
        "type": "object",
        "description": "**Tag filter** — a three-way set predicate over tag ids. Used by\nACL grants, right presets and transitions to limit applicability\nto objects carrying (or not carrying) specific tags.\n\nA match succeeds when **all** non-empty conditions hold: every id\nin `all` is present on the object, *at least one* id in `any` is\npresent, and *no* id in `not` is present.\n",
        "properties": {
          "all": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Every listed tag must be present on the object."
          },
          "any": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "At least one listed tag must be present. Empty / absent means\n\"no any-constraint\".\n"
          },
          "not": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "None of the listed tags may be present."
          },
          "changed": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Only used by transitions — the tags whose addition / removal\nshould *trigger* the transition. Omitted everywhere else.\n"
          }
        }
      },
      "SystemFieldApi": {
        "type": "object",
        "description": "Per-mask configuration for the **system fields** — the fields fylr\nattaches to every object regardless of the user datamodel\n(`_id_parent`, `_id`, `_tags`, `_acl`, `_owner`, `_pool`,\n`_collections`, `_publish`). Each present key carries the visibility\n/ inline / edit settings the mask applies to that system field.\nOnly present on top-level masks; sub-masks inherit.\n",
        "properties": {
          "parent": {
            "$ref": "#/components/schemas/SystemFieldDefApi",
            "description": "Settings for the `_id_parent` field (hierarchical link)."
          },
          "object_id": {
            "$ref": "#/components/schemas/SystemFieldDefApi",
            "description": "Settings for the `_id` (system object id) field."
          },
          "tags": {
            "$ref": "#/components/schemas/SystemFieldDefApi",
            "description": "Settings for the `_tags` field."
          },
          "acl": {
            "$ref": "#/components/schemas/SystemFieldDefApi",
            "description": "Settings for the `_acl` field."
          },
          "owner": {
            "$ref": "#/components/schemas/SystemFieldDefApi",
            "description": "Settings for the `_owner` field."
          },
          "pool": {
            "$ref": "#/components/schemas/SystemFieldDefApi",
            "description": "Settings for the `_pool` field."
          },
          "collections": {
            "$ref": "#/components/schemas/SystemFieldDefApi",
            "description": "Settings for the `_collections` field."
          },
          "publish": {
            "$ref": "#/components/schemas/SystemFieldDefApi",
            "description": "Settings for the `_publish` field."
          }
        }
      },
      "SystemFieldDefApi": {
        "type": "object",
        "description": "Per-system-field rendering / editing options on a mask. Each key\ncontrols one aspect of how the corresponding system field is\npresented in the front-end. All sub-fields are optional; omitted\nentries mean \"use the default behaviour\".\n",
        "properties": {
          "inline": {
            "type": "string",
            "description": "Inline rendering directive — when set, the front-end embeds\nthe system field's value alongside other fields rather than\nin the standard sidebar. Recognised values are\nfront-end-defined.\n"
          },
          "mask_id": {
            "description": "Mask the system field should render through (when the field\nlinks to objects of another type, like `_owner`). Either an\ninteger mask id or the special string `\"standard\"`.\n",
            "oneOf": [
              {
                "type": "integer",
                "format": "int64"
              },
              {
                "type": "string",
                "enum": [
                  "standard"
                ]
              }
            ]
          },
          "output": {
            "$ref": "#/components/schemas/SystemFieldDefModeApi",
            "description": "Output (detail / table / text) display mode for the field."
          },
          "edit": {
            "$ref": "#/components/schemas/SystemFieldDefModeApi",
            "description": "Edit mode for the field (`edit` / `show` / `off`)."
          }
        }
      },
      "SystemFieldDefModeApi": {
        "type": "object",
        "description": "Per-mode display setting for a system field (output or edit). Used\ninside `SystemFieldDefApi.output` / `.edit`.\n",
        "properties": {
          "mode": {
            "type": "string",
            "description": "The mode the system field should use in this context.\nRecognised values include `show`, `edit`, `off`,\n`hide`, `inline`. The set is front-end-defined; unknown\nvalues are silently ignored by the editor.\n"
          }
        }
      },
      "SuggestRequest": {
        "type": "object",
        "description": "Auto-suggest request — accepted as the JSON request body of\n`POST /api/v1/suggest`, and as the value of the `BODY` query\nparameter on `GET /api/v1/suggest`. Drives token and / or field\ncompletion through the search index.\n\nEach result kind is opted into independently: token suggestions\n(`tokens`, on by default unless `tokens` is `false`), per-field\nvalue matches (`fields_suggest: true`, which also needs a non-empty\n`fields`), and linked-object descriptors (a non-null\n`linked_objecttypes`).\n",
        "properties": {
          "query": {
            "type": "string",
            "description": "The user's current input. Optional; defaults to the empty\nstring. Tokenised (whitespace-split) unless\n`tokens_dont_split_query` is set. The last token is treated as\nthe partial term to complete.\n"
          },
          "tokens_dont_split_query": {
            "type": "boolean",
            "default": false,
            "description": "If true, the query is sent verbatim — the engine does not split\nit on whitespace. Useful when the input is a multi-word phrase\nthat should match as a single token.\n"
          },
          "tokens": {
            "type": "boolean",
            "nullable": true,
            "description": "If true, null, or omitted, return token completions in\n`suggestions.tokens`. Set to false to suppress them. Independent\nof `fields_suggest`.\n"
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Field paths whose values should be considered as completion\ncandidates. Each entry is a fully-qualified field name\n(e.g. `picture.title`, `_tags.tag.name`). Must be non-empty to\nget any per-field suggestions: combining `fields_suggest: true`\nwith an empty `fields` yields no `suggestions.fields` (it is a\nsilent no-op, not an error).\n"
          },
          "fields_suggest": {
            "type": "boolean",
            "default": false,
            "description": "If true, also return per-field completions in\n`suggestions.fields` — one entry per matching value, with the\nlist of system-object ids that hold it.\n"
          },
          "objecttypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Restrict suggestions to objects of these objecttypes. Empty /\nomitted means no restriction.\n"
          },
          "pool_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Restrict suggestions to objects in exactly these pools — there\nis no automatic sub-pool inclusion. Empty / omitted means no\nrestriction.\n"
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Restrict token / field matching to these language-tagged\nsub-fields (e.g. `de-DE`, `en-US`). Empty means consider all\nlanguages enabled on the instance.\n"
          },
          "linked_objecttypes": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "If set, the engine also returns `linked_objects` — full\n`ObjectApi` entries of the named objecttypes that match the\nquery. By default every match is returned, referenced or not;\nset `linked_objects_referenced_by_objecttypes` to keep only the\nones actually in use. Useful for autocomplete pickers that need\nto show the target object inline.\n"
          },
          "linked_objects_referenced_by_objecttypes": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "Opt-in filter for `linked_objects`. When set, a linked-object\nsuggestion is kept only if at least one record of these\nobjecttypes links to it (directly, nested or reverse — the\n`_linked.\u003cot\u003e._id` closure the \"in\" filter queries when a\nsuggestion is clicked), so selecting the suggestion as a search\nfilter over these objecttypes always yields results. Absent /\nempty returns every match. Pass the objecttypes the caller will\nactually filter on click — kept separate from `objecttypes` on\npurpose, since `objecttypes` may be widened with the linked\nobjecttypes so token matches inside linked objects are found.\n"
          },
          "analyze_wildcards": {
            "type": "boolean",
            "default": false,
            "description": "If true, the query string is interpreted as a wildcard pattern\n(`*` and `?`) rather than a prefix. Applies to token\nsuggestions only; the field and linked-object searches ignore\nit.\n"
          },
          "tokens_mode": {
            "type": "string",
            "enum": [
              "",
              "ngram",
              "edgengram",
              "exact"
            ],
            "description": "Token-matching mode. One of:\n\n  * `` (empty) / `ngram` — substring match (default).\n  * `edgengram` — prefix match.\n  * `exact` — exact-term match.\n\nAny other value is rejected with a 400.\n"
          },
          "timeout": {
            "type": "integer",
            "description": "Per-request timeout in milliseconds passed through to the\nsearch index. Zero / omitted uses the indexer's default.\n"
          },
          "limit": {
            "type": "integer",
            "default": 10,
            "description": "Maximum number of suggestions to return (per kind). Defaults\nto 10 when unset or zero.\n"
          }
        },
        "example": {
          "query": "fahr",
          "fields": [
            "objects.title_loca"
          ],
          "fields_suggest": true
        }
      },
      "SuggestResponse": {
        "type": "object",
        "description": "Auto-suggest response — returned by `GET /api/v1/suggest` and\n`POST /api/v1/suggest`. Carries diagnostic timing info plus a\n`suggestions` envelope with the three optional result sets the\nrequest opted into.\n",
        "required": [
          "suggestions"
        ],
        "properties": {
          "es_time": {
            "type": "integer",
            "format": "int64",
            "description": "Time the search index spent on the request, in milliseconds.\nExcludes fylr-side serialisation overhead.\n"
          },
          "timed_out": {
            "type": "boolean",
            "description": "True if the request reached the per-request `timeout`. Partial\nresults may still be present in `suggestions`.\n"
          },
          "suggestions": {
            "type": "object",
            "description": "Result envelope. Each sub-field is present only when its\nmatching request flag opted in: `tokens` is present unless\n`tokens` was `false`; `fields` is present when `fields_suggest`\nis true; `linked_objects` is present whenever\n`linked_objecttypes` is non-null (an empty `linked_objecttypes`\narray yields an empty `linked_objects` list).\n",
            "properties": {
              "tokens": {
                "type": "array",
                "nullable": true,
                "items": {
                  "type": "object",
                  "required": [
                    "suggest",
                    "tokens",
                    "count"
                  ],
                  "properties": {
                    "suggest": {
                      "type": "string",
                      "description": "The rendered suggestion with the matched prefix\nwrapped in `\u003cb\u003e...\u003c/b\u003e` tags — ready to drop into\nthe front-end picker.\n"
                    },
                    "tokens": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The individual tokens this suggestion is composed of\n(front-end uses this for keyboard navigation).\n"
                    },
                    "count": {
                      "type": "integer",
                      "description": "Number of indexed documents the term occurs in."
                    }
                  }
                }
              },
              "fields": {
                "type": "array",
                "nullable": true,
                "items": {
                  "type": "object",
                  "required": [
                    "field",
                    "suggest",
                    "count"
                  ],
                  "properties": {
                    "field": {
                      "type": "string",
                      "description": "The complete matched field value, in plain text\n(HTML-unescaped). This is the value itself, not the\nfield path the request asked for.\n"
                    },
                    "suggest": {
                      "type": "string",
                      "description": "The same value, HTML-escaped, with the matched part\nwrapped in `\u003cb\u003e...\u003c/b\u003e` tags — ready to drop into the\nfront-end picker.\n"
                    },
                    "count": {
                      "type": "integer",
                      "description": "Number of indexed documents that hold the value at\nthat field.\n"
                    },
                    "_system_object_id": {
                      "type": "array",
                      "items": {
                        "type": "integer",
                        "format": "int64"
                      },
                      "description": "System-object ids of the matching documents — capped\nby the request's `limit`. Lets the front end jump\nstraight to the underlying object.\n"
                    }
                  }
                }
              },
              "linked_objects": {
                "type": "array",
                "nullable": true,
                "items": {
                  "type": "object",
                  "additionalProperties": true
                },
                "description": "Full object descriptors of the linked objects whose\nobjecttypes are in `linked_objecttypes`. Each entry is an\n`ObjectApi` rendered in the search \"standard\" format — a\n`_standard` map keyed by mask id, mirroring the search\noutput. Only objects that a record of the searched\n`objecttypes` actually links to are returned, so selecting\none as a search filter yields results. Useful for picker\nUIs that need to render a label alongside the suggestion.\nPresent whenever `linked_objecttypes` is non-null; an empty\n`linked_objecttypes` array yields an empty list.\n"
              }
            }
          }
        },
        "example": {
          "suggestions": {
            "tokens": [
              {
                "suggest": "\u003cb\u003efahr\u003c/b\u003ebar",
                "tokens": [
                  "fahrbar"
                ],
                "count": 1
              },
              {
                "suggest": "\u003cb\u003efahr\u003c/b\u003erad",
                "tokens": [
                  "fahrrad"
                ],
                "count": 1
              }
            ],
            "fields": [
              {
                "field": "fahrrad",
                "suggest": "\u003cb\u003efahrrad\u003c/b\u003e",
                "count": 1,
                "_system_object_id": [
                  100
                ]
              },
              {
                "field": "fahrbar",
                "suggest": "\u003cb\u003efahrbar\u003c/b\u003e",
                "count": 1,
                "_system_object_id": [
                  101
                ]
              }
            ],
            "linked_objects": [
              {
                "_standard": {
                  "1": {
                    "text": {
                      "de-DE": "henk 18"
                    }
                  }
                }
              }
            ]
          }
        }
      },
      "LocaApi": {
        "type": "object",
        "description": "Datamodel translation document — a flat map of dotted **loca keys**\nto per-language values (`LocaValue`).\n\nThe key set is generated from the datamodel — every objecttype,\nmask, column, link and splitter contributes its own keys.\nReading clients should treat any key as opaque and look it up\nby exact match. **`POST /l10n/user/HEAD` is a full replace**: any\ngenerated key omitted from the body is cleared, so always send the\ncomplete document (typically the body returned by\n`GET /l10n/user/HEAD`). Unknown keys are ignored (not rejected);\nlanguage entries whose tag starts with `_` and empty-string values\nare dropped on write.\n\nKey patterns currently in use:\n\n  * `schema.\u003cobjecttype\u003e.name` — objecttype label.\n  * `schema.\u003cobjecttype\u003e.column.\u003ccolumn\u003e` — column label.\n  * `schema.\u003cobjecttype\u003e.column.\u003cother_objecttype\u003e` — link-column label\n    (`nested`).\n  * `schema.\u003cobjecttype\u003e.column.reverse:\u003cother_objecttype\u003e.\u003cother_column_api_id\u003e`\n    — reverse-link column label.\n  * `schema.\u003cobjecttype\u003e.column.reverse:\u003cobjecttype\u003e` — hierarchical\n    reverse-link column label.\n  * `mask.\u003cobjecttype_api_id\u003e.\u003cmask\u003e.name` — mask label.\n  * `mask.\u003cobjecttype_api_id\u003e.\u003cmask\u003e.\u003cother_objecttype_api_id\u003e.field.\u003ccolumn_api_id\u003e.{edit_user_hint|output_user_hint|search_user_hint}`\n    — user-hint texts for a regular field.\n  * `mask.\u003cobjecttype_api_id\u003e.\u003cmask\u003e.\u003cother_objecttype_api_id\u003e.link.\u003ccolumn_api_id\u003e.{edit_user_hint|output_user_hint|search_user_hint}`\n    — user-hint texts for a link field.\n  * `mask.\u003cobjecttype_api_id\u003e.\u003cmask\u003e.\u003cother_objecttype_api_id\u003e.linked-table.\u003ccolumn_api_id\u003e.{edit_user_hint|output_user_hint|search_user_hint}`\n    — user-hint texts for a nested link.\n  * `mask.\u003cobjecttype_api_id\u003e.\u003cmask\u003e.\u003cother_objecttype_api_id\u003e.reverse-linked-table.\u003ccolumn_api_id\u003e.{edit_user_hint|output_user_hint|search_user_hint}`\n    — user-hint texts for a reverse link.\n  * `mask.\u003cobjecttype_api_id\u003e.\u003cmask\u003e.splitter.\u003cindex\u003e` — splitter label.\n",
        "additionalProperties": {
          "$ref": "#/components/schemas/LocaValue"
        },
        "example": {
          "schema.category.name": {
            "de-DE": "Kategorie DE",
            "en-US": "Kategorie US"
          },
          "schema.category.column.name": {
            "de-DE": "Name DE",
            "en-US": "Name US"
          },
          "mask.4.category__all_fields.name": {
            "de-DE": "Kategorien"
          },
          "mask.4.category__all_fields.4.field.10.edit_user_hint": {
            "de-DE": "Name Hinweis DE",
            "en-US": "Name Hinweis US",
            "_comment": "category.name"
          },
          "mask.4.category__all_fields.splitter.2": {
            "de-DE": "Splitter DE",
            "en-US": "Splitter US"
          }
        }
      },
      "RightsCatalog": {
        "type": "object",
        "description": "The **rights catalog** — the full inventory of right definitions,\ncapabilities and saved presets known to this fylr instance,\npartitioned by context.\n\nThis is the response of `GET /right`. Clients use it to render\npermission UIs (preset editors, ACL bag editors) and to discover\nwhich rights are available in each context.\n\nPlugins extend the catalog by contributing additional rights to\nthe `system` context (named `plugin.\u003cplugin_name\u003e.\u003cright\u003e`).\n",
        "required": [
          "system",
          "pool",
          "object",
          "collection",
          "tag",
          "user",
          "group",
          "objecttype-without-pool"
        ],
        "properties": {
          "system": {
            "$ref": "#/components/schemas/RightsContextInfo",
            "description": "System rights (instance-wide permissions, plugin rights)."
          },
          "pool": {
            "$ref": "#/components/schemas/RightsContextInfo",
            "description": "Rights that apply to objects via pool ACLs."
          },
          "object": {
            "$ref": "#/components/schemas/RightsContextInfo",
            "description": "Rights that apply to individual objects."
          },
          "collection": {
            "$ref": "#/components/schemas/RightsContextInfo",
            "description": "Rights that apply to collections."
          },
          "tag": {
            "$ref": "#/components/schemas/RightsContextInfo",
            "description": "Rights that apply to tags."
          },
          "user": {
            "$ref": "#/components/schemas/RightsContextInfo",
            "description": "Rights that apply to users."
          },
          "group": {
            "$ref": "#/components/schemas/RightsContextInfo",
            "description": "Rights that apply to groups."
          },
          "objecttype-without-pool": {
            "$ref": "#/components/schemas/RightsContextInfo",
            "description": "Rights that apply to objecttypes that don't participate in pool\nACLs (objecttypes whose `acl: false`).\n"
          }
        }
      },
      "RightsContextInfo": {
        "type": "object",
        "description": "Per-context entry of the rights catalog — capabilities, the\nright definitions available in this context, and (where the\ncontext supports them) the saved presets.\n",
        "required": [
          "capabilities",
          "rights"
        ],
        "properties": {
          "capabilities": {
            "$ref": "#/components/schemas/RightsCapabilities"
          },
          "rights": {
            "type": "array",
            "description": "The right definitions available in this context. Each entry\nis either a regular right or a `choice` group whose `rights`\narray carries the mutually-exclusive options.\n",
            "items": {
              "$ref": "#/components/schemas/RightDef"
            }
          },
          "presets": {
            "type": "array",
            "description": "Saved presets for this context, in display order. Only\npopulated for contexts that support presets (`object`,\n`collection`).\n",
            "items": {
              "$ref": "#/components/schemas/PresetApi"
            }
          }
        }
      },
      "RightsCapabilities": {
        "type": "object",
        "description": "Per-right capability flags for a context — which rights can be\nmarked `active`, which are eligible for a preset, which accept a\ntag filter, which are considered structurally valid for the\ncontext, and which are sticky (cannot be removed once granted).\n\nEach map is keyed by right name; the value is currently a free-form\nstring describing the capability flavour (commonly `\"true\"` or a\npolicy keyword).\n",
        "properties": {
          "active": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Rights that may be enabled (`active: true`) in this context.\n"
          },
          "preset": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Rights that may appear in a preset for this context."
          },
          "tagfilter": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Rights that accept a tag filter (`_tagfilter`) in this context."
          },
          "valid": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Rights that are structurally valid for this context. A grant\nfor a right not listed here is silently dropped by the ACL\npipeline.\n"
          },
          "sticky": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Sticky rights — once granted, the ACL cannot have them removed\nby lower-privileged updates.\n"
          }
        }
      },
      "RightDef": {
        "type": "object",
        "x-recursion": true,
        "description": "A **right definition** — one entry in the rights catalog. A\ndefinition is either a regular right (`type` empty or `\"right\"`)\nor a `choice` group whose `rights` array carries the\nmutually-exclusive options the user picks one of.\n",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "",
              "right",
              "choice"
            ],
            "description": "`\"\"` and `\"right\"` mean a regular right. `\"choice\"` means a\ngroup of mutually-exclusive sub-rights — the `rights` array\nthen carries the options.\n"
          },
          "name": {
            "type": "string",
            "description": "Stable, machine-readable right name. For choice groups, the\nname is shared by the picker; for regular rights, it's the\nidentifier used in ACL grants.\n"
          },
          "comment": {
            "type": "string",
            "description": "Optional human-readable description."
          },
          "group": {
            "type": "string",
            "description": "Logical grouping the UI uses to lay the right out next to\nrelated rights.\n"
          },
          "has_grantable": {
            "type": "boolean",
            "description": "Whether this right may be marked grantable in an ACL grant\n(the grantee can grant the same right onward).\n"
          },
          "parameters": {
            "type": "array",
            "description": "Parameters this right accepts in an ACL grant. Defaults are\nfilled in by the server; choice lists may be dynamic (e.g. the\nlist of EAS classes the instance has configured).\n",
            "items": {
              "$ref": "#/components/schemas/RightDefParam"
            }
          },
          "rights": {
            "type": "array",
            "description": "Sub-rights of a `choice` group — the mutually-exclusive\noptions the user picks one of. Only set when `type: choice`.\n",
            "items": {
              "$ref": "#/components/schemas/RightDef"
            }
          }
        }
      },
      "RightDefParam": {
        "type": "object",
        "description": "A parameter that an ACL grant may carry alongside a right —\ntypically a per-grant constraint like the list of mask names\nthe grant applies to, or a per-preset display setting.\n",
        "required": [
          "name",
          "type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "The parameter's identifier."
          },
          "type": {
            "type": "string",
            "description": "The parameter's data type. Common values:\n\n  * `bool` — boolean.\n  * `string` — single string.\n  * `string-list` — list of strings.\n  * `preview-versions` — list of `\u003cclass\u003e.\u003cversion\u003e` keys, with\n    `choices` populated from the instance's EAS configuration.\n  * `eas-class-list` — list of EAS class names, with `choices`\n    populated from the instance's EAS configuration.\n  * `mask-list` — list of mask names.\n",
            "examples": [
              "bool",
              "string-list",
              "preview-versions",
              "eas-class-list"
            ]
          },
          "comment": {
            "type": "string",
            "description": "Optional human-readable description."
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The closed list of allowed values (when applicable). For\ndynamic types (`preview-versions`, `eas-class-list`), the\nserver fills this in from the instance configuration.\n"
          },
          "merge_policy": {
            "type": "string",
            "description": "How conflicting values from multiple grants should be combined\ninto one effective value. Currently `less` is supported for\n`bool` parameters — the effective value is the AND of all\ngrants. Empty string means default merge.\n",
            "examples": [
              "",
              "less"
            ]
          }
        }
      },
      "FileStatBucketItem": {
        "type": "object",
        "description": "One leaf entry inside a `FileStatBucket.by_extension` /\n`by_class` map — the per-extension or per-class slice of the\nbucket's totals.\n",
        "required": [
          "size",
          "count"
        ],
        "properties": {
          "size": {
            "type": "integer",
            "format": "int64",
            "description": "Sum of file sizes, in bytes."
          },
          "count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of files."
          }
        }
      },
      "FileStatBucket": {
        "type": "object",
        "description": "One status bucket of file statistics — the totals for one\nlifecycle state (latest / history / deleted) of one storage\ncategory (originals / versions). The bucket carries the\nrolled-up `size` / `count` for the slice plus per-extension\nand per-class breakdowns.\n",
        "required": [
          "size",
          "count"
        ],
        "properties": {
          "size": {
            "type": "integer",
            "format": "int64",
            "description": "Sum of file sizes in this bucket, in bytes."
          },
          "count": {
            "type": "integer",
            "format": "int64",
            "description": "Number of files in this bucket."
          },
          "by_extension": {
            "type": "object",
            "description": "Per-file-extension breakdown of the bucket. Key is the\nlowercase extension without leading dot (e.g. `jpg`, `pdf`).\nOmitted when the bucket is empty.\n",
            "additionalProperties": {
              "$ref": "#/components/schemas/FileStatBucketItem"
            }
          },
          "by_class": {
            "type": "object",
            "description": "Per-EAS-class breakdown of the bucket. Key is the EAS class\nname (e.g. `image`, `document`, `audio`) as configured in\nthe base config. Omitted when the bucket is empty.\n",
            "additionalProperties": {
              "$ref": "#/components/schemas/FileStatBucketItem"
            }
          }
        }
      },
      "FileStatBuckets": {
        "type": "object",
        "description": "The three lifecycle buckets file statistics are sliced into —\nfiles that are still the current version of their object, files\nsuperseded by a newer version (history), and files belonging to\nsoft-deleted objects.\n",
        "required": [
          "latest",
          "history",
          "deleted"
        ],
        "properties": {
          "latest": {
            "$ref": "#/components/schemas/FileStatBucket",
            "description": "Files attached to the current version of live objects."
          },
          "history": {
            "$ref": "#/components/schemas/FileStatBucket",
            "description": "Files attached to historic (non-current) versions of live objects.\n"
          },
          "deleted": {
            "$ref": "#/components/schemas/FileStatBucket",
            "description": "Files attached to soft-deleted objects (the object has a\nnon-NULL `deleted_at`).\n"
          }
        }
      },
      "FileStats": {
        "type": "object",
        "description": "Aggregated file statistics — the file counts and storage usage\nrolled up across all objects in some scope (an objecttype, a pool,\na sub-tree, ...). The totals are sliced first by storage category\n(uploaded originals vs. derived versions) and then by lifecycle\n(latest / history / deleted).\n",
        "required": [
          "count",
          "size",
          "originals",
          "versions"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "format": "int64",
            "description": "Total file count across both originals and versions."
          },
          "size": {
            "type": "integer",
            "format": "int64",
            "description": "Total file size across both originals and versions, in bytes."
          },
          "originals": {
            "$ref": "#/components/schemas/FileStatBuckets",
            "description": "Statistics for **original** files — the file the user\nuploaded.\n"
          },
          "versions": {
            "$ref": "#/components/schemas/FileStatBuckets",
            "description": "Statistics for **derived** versions — previews, thumbnails,\nconverted formats produced from the originals.\n"
          }
        }
      },
      "ObjecttypeStats": {
        "type": "object",
        "description": "Asset statistics for one objecttype — the rolled-up file counts\nand storage usage across every object of the type.\n",
        "required": [
          "files"
        ],
        "properties": {
          "files": {
            "$ref": "#/components/schemas/FileStats"
          }
        }
      },
      "PoolStats": {
        "type": "object",
        "description": "Asset statistics for one pool — file counts and storage usage\nfor the objects in this pool (and, when the request set\n`include_subpools=true`, the transitive sub-tree).\n",
        "required": [
          "pool_id",
          "created_at",
          "files"
        ],
        "properties": {
          "pool_id": {
            "type": "integer",
            "format": "int64",
            "description": "The pool this stats document is for."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "RFC 3339 timestamp of when these stats were collected (for example\n`2024-01-01T00:00:00Z`). The pool stats query is expensive, so the\nresult may be served from a cache window.\n"
          },
          "files": {
            "$ref": "#/components/schemas/FileStats"
          }
        }
      },
      "PluginApiGET": {
        "type": "object",
        "description": "Response of `GET /plugin` — the inventory of enabled plugins plus\nthe URLs of their concatenated front-end bundles.\n",
        "required": [
          "plugins"
        ],
        "properties": {
          "bundle": {
            "$ref": "#/components/schemas/PluginBundle",
            "description": "URLs of the concatenated JS / CSS / HTML / l10n bundles, in\nload order. Omitted when bundling is disabled in the instance\nconfiguration.\n"
          },
          "plugins": {
            "type": "array",
            "description": "One descriptor per enabled plugin, ordered as loaded. Disabled\nplugins are not included.\n",
            "items": {
              "$ref": "#/components/schemas/PluginBase"
            }
          }
        },
        "example": {
          "plugins": [],
          "bundle": {
            "javascript": "https://example.fylr.io/api/v1/plugin/bundle.js",
            "css": "https://example.fylr.io/api/v1/plugin/bundle.css",
            "html": "https://example.fylr.io/api/v1/plugin/bundle.html",
            "l10n": "https://example.fylr.io/api/v1/plugin/bundle/l10n"
          }
        }
      },
      "PluginBundle": {
        "type": "object",
        "description": "URLs of the concatenated plugin front-end bundles. The endpoints\nthese point at (`/plugin/bundle.js`, `/plugin/bundle.css`,\n`/plugin/bundle.html`, `/plugin/bundle/l10n/{lang}.json`) merge\nthe assets of every enabled plugin in load order.\n",
        "properties": {
          "javascript": {
            "type": "string",
            "format": "uri",
            "description": "URL of the merged JavaScript bundle."
          },
          "css": {
            "type": "string",
            "format": "uri",
            "description": "URL of the merged CSS bundle."
          },
          "html": {
            "type": "string",
            "format": "uri",
            "description": "URL of the merged HTML template bundle."
          },
          "l10n": {
            "type": "string",
            "format": "uri",
            "description": "Prefix URL of the merged l10n bundle, e.g.\n`https://\u003chost\u003e/api/v1/plugin/bundle/l10n`. Clients append\n`/\u003clang\u003e.json` (for example `/de-DE.json`) to fetch\ntranslations for a specific language.\n"
          }
        }
      },
      "PluginBase": {
        "type": "object",
        "description": "Descriptor of one plugin as exposed by `GET /plugin` — the\npublicly-visible parts of the plugin's manifest plus the URLs\nthe front-end uses to fetch its assets.\n",
        "required": [
          "name",
          "version",
          "displayname"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "The plugin's unique identifier. Matches the directory name\nin the plugins folder and the `name:` from the manifest.\n",
            "examples": [
              "fylr-plugin-wordpress"
            ]
          },
          "version": {
            "type": "string",
            "description": "Plugin version, as declared in the manifest.",
            "examples": [
              "2.3.4"
            ]
          },
          "l10n": {
            "type": "string",
            "description": "Path (relative to the plugin's static URL) of the plugin's\nl10n CSV file.\n"
          },
          "server": {
            "type": "object",
            "description": "Server-side compatibility declarations.",
            "properties": {
              "api-version": {
                "type": "object",
                "properties": {
                  "require": {
                    "type": "integer",
                    "format": "int64",
                    "description": "The minimum fylr server API version this plugin\nsupports.\n"
                  }
                }
              }
            }
          },
          "url": {
            "type": "string",
            "description": "Optional homepage URL for the plugin (linked from the\nadmin UI).\n"
          },
          "displayname": {
            "$ref": "#/components/schemas/LocaValue",
            "description": "Localised display name."
          },
          "info": {
            "$ref": "#/components/schemas/LocaValue",
            "description": "Localised long description. Defaults to `\"-\"` in the\ninstance default language when the manifest does not\nprovide one.\n"
          },
          "webfrontend": {
            "type": "object",
            "description": "Free-form metadata the plugin contributes to the front-end\n(e.g. which routes / panels it registers). Shape is\nplugin-specific.\n",
            "additionalProperties": true
          },
          "custom": {
            "type": "object",
            "description": "Free-form `custom:` section from the manifest — published as-is\nso the plugin's front-end code can read its own configuration.\n",
            "additionalProperties": true
          },
          "base_url": {
            "type": "string",
            "format": "uri",
            "description": "URL the plugin's static assets are served from (set during\nthe API request).\n"
          },
          "plugin_url": {
            "type": "string",
            "format": "uri",
            "description": "URL of the plugin's own backend mount point (set during the\nAPI request).\n"
          },
          "build_info": {
            "$ref": "#/components/schemas/PluginBuildInfo"
          },
          "collection_upload": {
            "type": "object",
            "description": "Map of collection-upload integrations the plugin contributes\n(key = integration name). Value is the plugin's configuration\ndefinition for that integration.\n",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "PluginBuildInfo": {
        "type": "object",
        "description": "Build-time provenance of a plugin — repository, revision,\nrelease tag, and dates. Populated from the plugin's\n`build_info.json` (or equivalent) and included only when those\nvalues are non-empty.\n",
        "properties": {
          "repository": {
            "type": "string",
            "description": "Repository URL the plugin was built from."
          },
          "rev": {
            "type": "string",
            "description": "Git revision the build was made from."
          },
          "release": {
            "type": "string",
            "description": "Release tag of the build, if any."
          },
          "lastchanged": {
            "type": "string",
            "description": "Last-changed timestamp of the build source (free-form text;\nno fixed format).\n"
          },
          "builddate": {
            "type": "string",
            "description": "Build timestamp (free-form text; no fixed format).\n"
          }
        }
      },
      "SystemStats": {
        "type": "object",
        "description": "System statistics — per-objecttype and per-basetype object counts,\nindex-queue depth, file processing queues, and per-index storage\nstats. Returned by `GET /system/status`.\n\nBuild / version / capability information is **not** in this body\n— it travels in the `x-fylr-status` response header, in the form\n`\u003cconfig\u003e-\u003cinstance\u003e-\u003cversion\u003e \u003cbuild_commit\u003e` plus per-component\nflags (use the inspect UI's status page for the rendered view).\n",
        "required": [
          "objecttypes",
          "basetypes",
          "indices_objects",
          "total_not_indexed",
          "pending_files",
          "queued_files",
          "file_stats",
          "indices_stats"
        ],
        "properties": {
          "objecttypes": {
            "type": "array",
            "description": "Per-user-objecttype counts.",
            "items": {
              "$ref": "#/components/schemas/SystemTypeStats"
            }
          },
          "basetypes": {
            "type": "array",
            "description": "Per-basetype counts (`collection`, `event`, `group`,\n`message`, `pool`, `term`, `user`).\n",
            "items": {
              "$ref": "#/components/schemas/SystemTypeStats"
            }
          },
          "indices_objects": {
            "type": "object",
            "description": "Per-index object counts, broken down by basetype/objecttype.\nOuter key is the index name (`BaseRead`, `BaseWrite`,\n`ObjectRead`, `ObjectWrite`); inner key is the term value\n(`_basetype` / `_objecttype` / `_masks`).\n",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          "total_not_indexed": {
            "type": "integer",
            "description": "Sum of objects still waiting in the index queue across all\ntypes.\n"
          },
          "pending_files": {
            "type": "integer",
            "description": "Number of files in the \"pending\" pipeline state (waiting to\nbe processed by the execserver).\n"
          },
          "queued_files": {
            "type": "integer",
            "description": "Number of files queued for processing — superset of\n`pending_files` that includes retries.\n"
          },
          "file_stats": {
            "type": "array",
            "description": "Counts of files grouped by processing status.",
            "items": {
              "$ref": "#/components/schemas/SystemFileStat"
            }
          },
          "indices_stats": {
            "type": "array",
            "description": "Per-index storage sizes.",
            "items": {
              "$ref": "#/components/schemas/SystemIndicesStats"
            }
          }
        }
      },
      "SystemTypeStats": {
        "type": "object",
        "description": "Aggregated counts for one objecttype or basetype — total stored\nobjects, index status counts, and per-file timing / size averages.\n",
        "required": [
          "type_name"
        ],
        "properties": {
          "type_name": {
            "type": "string",
            "description": "Objecttype or basetype name."
          },
          "total_count": {
            "type": "integer",
            "description": "Number of stored objects of this type."
          },
          "indexed_count": {
            "type": "integer",
            "description": "Subset of `total_count` that is currently in the search index."
          },
          "not_indexed_count": {
            "type": "integer",
            "description": "Subset of `total_count` still waiting in the index queue."
          },
          "error_count": {
            "type": "integer",
            "description": "Objects of this type whose last indexing attempt errored."
          },
          "avg_time": {
            "type": "number",
            "description": "Average indexing time per object, in seconds."
          },
          "avg_size": {
            "type": "integer",
            "format": "int64",
            "description": "Average serialised size per object, in bytes."
          },
          "total_size": {
            "type": "integer",
            "format": "int64",
            "description": "Sum of `avg_size * total_count`, in bytes."
          }
        }
      },
      "SystemFileStat": {
        "type": "object",
        "description": "Count of files in one processing status. Used inside\n`SystemStats.file_stats`.\n",
        "required": [
          "status",
          "count"
        ],
        "properties": {
          "status": {
            "type": "string",
            "description": "File processing status — one of the values fylr's file\npipeline assigns (e.g. `pending`, `queued`, `done`, `error`).\n"
          },
          "count": {
            "type": "integer",
            "description": "Number of files in this status."
          }
        }
      },
      "SystemIndicesStats": {
        "type": "object",
        "description": "Storage size of one search index. Used inside\n`SystemStats.indices_stats`.\n",
        "required": [
          "name",
          "index",
          "size"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Logical index role (`BaseRead`, `BaseWrite`, `ObjectRead`,\n`ObjectWrite`).\n"
          },
          "index": {
            "type": "string",
            "description": "The physical index name this role currently resolves to."
          },
          "size": {
            "type": "string",
            "description": "Storage size of the index, as reported by Elasticsearch\n(human-readable string such as `42mb`).\n"
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "description": "The result of a search.",
        "required": [
          "count",
          "offset",
          "limit",
          "objects"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "The search domain, echoed from the request."
          },
          "objecttypes": {
            "type": "array",
            "description": "The object types that were searched.",
            "items": {
              "type": "string"
            }
          },
          "language": {
            "type": "string",
            "description": "Primary language of the result."
          },
          "count": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of objects matching the search."
          },
          "offset": {
            "type": "integer",
            "description": "Offset of the returned page within the full result."
          },
          "limit": {
            "type": "integer",
            "description": "Maximum number of objects in the returned page."
          },
          "format": {
            "type": "string",
            "description": "Render format of the objects in the response."
          },
          "merge_linked_objects": {
            "type": "string",
            "description": "The `merge_linked_objects` mode applied, echoed from the request."
          },
          "merge_max_depth": {
            "type": "integer",
            "description": "The `merge_max_depth` applied, echoed from the request."
          },
          "objects": {
            "type": "array",
            "description": "The page of matching objects. The shape of each item depends on the\nsearch `type`: rendered objects for an object search, otherwise pools,\ncollections, events, messages or users/groups. Each object search hit\ncarries its relevance in `_score` (number): sort by `_score` to order\nby relevance, raise it for selected search elements with their `boost`\nparameter.\n",
            "items": {}
          },
          "aggregations": {
            "type": "object",
            "description": "The computed aggregations, keyed by the names used in the request.",
            "additionalProperties": true
          },
          "point_in_time": {
            "type": "object",
            "description": "The point-in-time context used or opened for this search.",
            "properties": {
              "id": {
                "type": "string"
              },
              "keep_alive": {
                "type": "string"
              }
            }
          }
        }
      },
      "SearchRequestSort": {
        "type": "object",
        "description": "One sort criterion of a search.",
        "required": [
          "field"
        ],
        "properties": {
          "field": {
            "type": "string",
            "description": "Field to sort by. Use `_score` to sort by relevance."
          },
          "order": {
            "type": "string",
            "description": "Sort direction. Defaults to `asc`.",
            "enum": [
              "asc",
              "desc"
            ]
          },
          "language": {
            "type": "string",
            "description": "For localized fields, the language to sort by."
          },
          "with_path": {
            "type": "boolean",
            "description": "Sort hierarchical fields by their full path."
          },
          "mode": {
            "type": "string",
            "description": "How to pick a sort value when the field has several values."
          },
          "numeric": {
            "type": "boolean",
            "description": "Sort the field numerically rather than as text."
          },
          "number_groups": {
            "type": "array",
            "description": "Number group boundaries used for numeric grouping.",
            "items": {
              "type": "integer",
              "format": "int64"
            }
          },
          "width": {
            "type": "string",
            "description": "For date fields, the bucket width to sort by.",
            "enum": [
              "year",
              "month",
              "week",
              "day"
            ]
          }
        }
      },
      "SearchAggregation": {
        "type": "object",
        "description": "One aggregation computed over the search result. Aggregations are keyed by a\nclient-chosen name in the request and the response.\n",
        "properties": {
          "type": {
            "type": "string",
            "description": "Aggregation kind, for example a term aggregation, a date range\naggregation or a geo tile grid.\n"
          },
          "field": {
            "type": "string",
            "description": "Field to aggregate over."
          },
          "value_field": {
            "type": "string",
            "description": "Field whose value is reported for each bucket."
          },
          "objecttype": {
            "type": "string",
            "description": "Restrict the aggregation to this object type."
          },
          "limit": {
            "type": "integer",
            "description": "Maximum number of buckets to return."
          },
          "offset": {
            "type": "integer",
            "description": "Number of buckets to skip."
          },
          "sort": {
            "type": "string",
            "description": "Bucket sort criterion."
          },
          "order": {
            "type": "string",
            "description": "Bucket sort direction."
          },
          "format": {
            "type": "string",
            "description": "Render format for objects reported in buckets."
          },
          "include": {
            "type": "string",
            "description": "Regular expression limiting which bucket keys are returned."
          },
          "language": {
            "type": "string",
            "description": "For localized fields, the language to aggregate."
          },
          "filter_parent": {
            "type": "integer",
            "format": "int64",
            "description": "Restrict buckets to children of this parent object."
          },
          "precision": {
            "type": "integer",
            "description": "Grid precision, for the `geotile_grid` aggregation."
          },
          "ranges": {
            "type": "array",
            "description": "Explicit ranges, for a date range aggregation.",
            "items": {
              "type": "object",
              "properties": {
                "from": {
                  "type": "string"
                },
                "to": {
                  "type": "string"
                }
              }
            }
          },
          "bounds": {
            "type": "object",
            "description": "Bounding box that limits a geo aggregation."
          }
        }
      },
      "SearchRequestField": {
        "type": "object",
        "description": "Selects a field whose values are collected for each hit when the search\nrequest uses `fields`.\n",
        "properties": {
          "key": {
            "type": "string",
            "description": "Name this field appears under in the response."
          },
          "field": {
            "type": "string",
            "description": "The field to collect."
          },
          "with_path": {
            "type": "boolean",
            "description": "Collect the full path for hierarchical fields."
          },
          "mode": {
            "type": "string",
            "description": "How to pick a value when the field has several values."
          },
          "language": {
            "type": "string",
            "description": "For localized fields, the language to collect."
          }
        }
      },
      "SearchParseOptions": {
        "type": "object",
        "description": "Options for parsing a query string at `/search/parse`.",
        "required": [
          "query"
        ],
        "properties": {
          "query": {
            "type": "string",
            "description": "The query string to parse."
          },
          "objecttypes": {
            "type": "array",
            "description": "Restrict the search to these object types.",
            "items": {
              "type": "string"
            }
          },
          "search": {
            "type": "boolean",
            "description": "If `true`, run the parsed search and return its result instead of the\nparsed `SearchRequest`.\n"
          },
          "limit": {
            "type": "integer",
            "description": "Maximum number of objects to return."
          },
          "offset": {
            "type": "integer",
            "description": "Number of objects to skip before the first returned object."
          },
          "format": {
            "type": "string",
            "description": "Render format for the objects in the result."
          },
          "timezone": {
            "type": "string",
            "description": "Timezone used when interpreting dates in the query string."
          }
        }
      },
      "XmlMappingTagCatalog": {
        "type": "object",
        "description": "The metadata **tag catalog** returned by `GET /xmlmapping/tags`\nwith the default `exif_list` recipe — the JSON conversion of\n`exiftool -f -listx`, produced by `fylr metadata list`.\n",
        "properties": {
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/XmlMappingTag"
            },
            "description": "One entry per known tag, deduplicated by `\u003cgroup\u003e:\u003ctag\u003e` path.\n"
          },
          "xmlns": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "XML namespace URI by tag group, following exiftool's\n`http://ns.exiftool.ca/\u003cfamily0\u003e/\u003cfamily1\u003e/1.0/` convention.\n",
            "example": {
              "AAC": "http://ns.exiftool.ca/AAC/AAC/1.0/"
            }
          },
          "exiftool_version": {
            "type": "string",
            "description": "The version of the exiftool binary that produced the catalog.",
            "example": "13.50"
          }
        }
      },
      "SearchRequest": {
        "type": "object",
        "x-recursion": true,
        "description": "Describes a search to run against **fylr**. The `search` property holds\nthe query; the remaining properties control paging, sorting, the response\nformat and aggregations.\n",
        "properties": {
          "type": {
            "type": "string",
            "description": "Domain to search. Omit (or use an empty string) to search indexed\nobjects. Each other domain has its own object shape in the response.\n",
            "enum": [
              "pool",
              "collection",
              "event",
              "message",
              "user",
              "group",
              "acl"
            ]
          },
          "objecttypes": {
            "type": "array",
            "description": "Restrict the search to these object types. When empty, all object\ntypes are searched.\n",
            "items": {
              "type": "string"
            }
          },
          "search": {
            "type": "array",
            "description": "The query: a list of search elements combined into a single boolean\nquery.\n",
            "items": {
              "$ref": "#/components/schemas/SearchObject"
            }
          },
          "offset": {
            "type": "integer",
            "description": "Number of hits to skip before the first returned object."
          },
          "limit": {
            "type": "integer",
            "description": "Maximum number of objects to return."
          },
          "format": {
            "type": "string",
            "description": "Render format for the objects in the response, for example `standard`\nor `long`.\n"
          },
          "merge_linked_objects": {
            "type": "string",
            "description": "Controls whether linked objects are embedded into the hits.",
            "enum": [
              "none",
              "in_main_search",
              "not_in_main_search",
              "not_in_main_search_unless_reverse",
              "all"
            ]
          },
          "merge_max_depth": {
            "type": "integer",
            "description": "Maximum depth up to which linked objects are embedded when\n`merge_linked_objects` is used.\n"
          },
          "languages": {
            "type": "array",
            "description": "Languages to load for localized fields.",
            "items": {
              "type": "string"
            }
          },
          "sort": {
            "type": "array",
            "description": "Sort order of the result. Criteria are applied in order.",
            "items": {
              "$ref": "#/components/schemas/SearchRequestSort"
            }
          },
          "include_deleted": {
            "type": "boolean",
            "description": "If `true`, objects in the trash are included in the result."
          },
          "aggregations": {
            "type": "object",
            "description": "Aggregations to compute over the result, keyed by a name chosen by the\nclient. The same names appear in the response.\n",
            "additionalProperties": {
              "$ref": "#/components/schemas/SearchAggregation"
            }
          },
          "fields": {
            "type": "array",
            "description": "Collect the values of specific fields for each hit, instead of (or in\naddition to) returning whole objects.\n",
            "items": {
              "$ref": "#/components/schemas/SearchRequestField"
            }
          },
          "field": {
            "type": "string",
            "description": "Field name used when this request is a sub search."
          },
          "include_fields": {
            "type": "array",
            "description": "If set, only these fields are included in the returned objects.",
            "items": {
              "type": "string"
            }
          },
          "exclude_fields": {
            "type": "array",
            "description": "Fields to omit from the returned objects.",
            "items": {
              "type": "string"
            }
          },
          "point_in_time": {
            "type": "object",
            "description": "Run the search against a point-in-time snapshot of the index, for\nstable paging across requests. See `DELETE /search/point_in_time`.\n",
            "properties": {
              "id": {
                "type": "string",
                "description": "ID of the point-in-time context."
              },
              "keep_alive": {
                "type": "string",
                "description": "How long the context is kept alive, for example `1m`."
              }
            }
          },
          "search_after": {
            "type": "array",
            "description": "Cursor for deep pagination: the `sort` values of the last hit of the\nprevious page. Use instead of a large `offset`.\n",
            "items": {}
          },
          "file_url_expire": {
            "type": "integer",
            "description": "Number of days the signed file URLs in the response stay valid."
          },
          "timezone": {
            "type": "string",
            "description": "Timezone used when interpreting and bucketing dates."
          },
          "generate_rights": {
            "type": "boolean",
            "description": "If `true`, the effective rights are generated for each hit."
          },
          "best_mask_filter": {
            "type": "boolean",
            "description": "If `true`, each object is reduced to the best mask the user may see.\n"
          }
        }
      },
      "SearchObject": {
        "type": "object",
        "x-recursion": true,
        "required": [
          "type"
        ],
        "description": "One element of a search query. The `type` selects how the element matches;\nwhich of the other properties apply depends on that `type`.\n",
        "properties": {
          "type": {
            "type": "string",
            "description": "Kind of match:\n  * `text`: full-text match of `string` / `query` against `fields`.\n  * `match`: like `text`, kept for compatibility.\n  * `in`: match a field against a set of values, an object type or a\n    `subsearch`.\n  * `range`: match a field against a `from` / `to` range.\n  * `changelog_range`: match objects by their changelog entries.\n  * `complex`: group nested elements in `search` as a boolean query.\n  * `nested`: like `complex`, but matches within the nested `path`.\n  * `geo_bounding_box`: match a geo field inside a bounding box.\n  * `geo_shape`: match a geo field against a shape.\n",
            "enum": [
              "text",
              "match",
              "in",
              "range",
              "changelog_range",
              "complex",
              "nested",
              "geo_bounding_box",
              "geo_shape"
            ]
          },
          "bool": {
            "type": "string",
            "description": "How this element combines with the other elements of the same `search`\nlist. Defaults to `must`.\n",
            "enum": [
              "must",
              "must_not",
              "should"
            ]
          },
          "boost": {
            "type": "number",
            "description": "Relative weight of this element: a higher boost results in a higher\n`_score` for objects matching it (useful with `bool: should` and\nsorting by `_score`). Applies to every `type`, must not be negative,\nhas no effect on `must_not` elements. Defaults to `1`.\n"
          },
          "fields": {
            "type": "array",
            "description": "Fields this element queries.",
            "items": {
              "type": "string"
            }
          },
          "string": {
            "type": "string",
            "description": "Search term, for `text` / `match`."
          },
          "query": {
            "type": "string",
            "description": "Alternative to `string` for `text` / `match`."
          },
          "phrase": {
            "type": "boolean",
            "description": "For `text`, match `string` as a phrase."
          },
          "mode": {
            "type": "string",
            "description": "Match mode for `text`, for example how tokens are combined."
          },
          "languages": {
            "type": "array",
            "description": "Restrict matching of localized fields to these languages.",
            "items": {
              "type": "string"
            }
          },
          "in": {
            "type": "array",
            "description": "For `in`, the set of values to match against.",
            "items": {}
          },
          "objecttype": {
            "type": "string",
            "description": "For `in`: match linked objects of this object type. Use `_pool` to\nmatch against pools.\n"
          },
          "include_path": {
            "type": "boolean",
            "description": "For `in` with `objecttype`: also match objects located on the path of\na hierarchical object type.\n"
          },
          "subsearch": {
            "$ref": "#/components/schemas/SearchRequest"
          },
          "field": {
            "type": "string",
            "description": "Single field, for `range` / `changelog_range`."
          },
          "from": {
            "description": "Lower bound, for `range` / `changelog_range`."
          },
          "to": {
            "description": "Upper bound, for `range` / `changelog_range`."
          },
          "from_equals": {
            "type": "boolean",
            "description": "Whether the `from` bound is inclusive. Defaults to `true`."
          },
          "to_equals": {
            "type": "boolean",
            "description": "Whether the `to` bound is inclusive. Defaults to `true`."
          },
          "path": {
            "type": "string",
            "description": "For `nested`, the nested field path the sub query runs in."
          },
          "search": {
            "type": "array",
            "description": "For `complex` / `nested`, the grouped sub elements.",
            "items": {
              "$ref": "#/components/schemas/SearchObject"
            }
          },
          "operation": {
            "type": "string",
            "description": "For `changelog_range`, the changelog operation to match."
          },
          "comment": {
            "type": "string",
            "description": "For `changelog_range`, the changelog comment to match."
          },
          "user": {
            "type": "integer",
            "format": "int64",
            "description": "For `changelog_range`, ID of the user who made the change."
          },
          "geo_bounding_box": {
            "type": "object",
            "description": "Bounding box for `type: geo_bounding_box`. Only this property and the\ncompanion `field` are used by that type; `field` is REQUIRED and must\nresolve to a geo field (for example `_standard.geo.1`). The box is\nforwarded to an OpenSearch `geo_bounding_box` query.\n\nProvide the two corners in exactly ONE of two mutually exclusive forms:\n  * point form: `top_left` / `bottom_right` as `{ lat, lon }` objects.\n  * geohash form: `top_left` / `bottom_right` as geohash strings.\nWhen decoding, the geohash (string) form is attempted first; if that\nfails the point (object) form is used. Both corners must use the same\nform.\n\nRequires a license with geo support; otherwise the search is rejected.\n",
            "required": [
              "top_left",
              "bottom_right"
            ],
            "additionalProperties": false,
            "properties": {
              "top_left": {
                "description": "Top-left corner of the box: either a `{ lat, lon }` point or a\ngeohash string. Must use the same form as `bottom_right`.\n",
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/GeoPoint"
                  },
                  {
                    "type": "string",
                    "description": "Geohash string, for example `gcr648nj4c0r`.",
                    "example": "gcr648nj4c0r"
                  }
                ]
              },
              "bottom_right": {
                "description": "Bottom-right corner of the box: either a `{ lat, lon }` point or a\ngeohash string. Must use the same form as `top_left`.\n",
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/GeoPoint"
                  },
                  {
                    "type": "string",
                    "description": "Geohash string, for example `tbn4zdz0b8hb`.",
                    "example": "tbn4zdz0b8hb"
                  }
                ]
              }
            },
            "examples": [
              {
                "top_left": {
                  "lat": 71.18507,
                  "lon": -25.2966
                },
                "bottom_right": {
                  "lat": 34.7982,
                  "lon": 41.7102
                }
              },
              {
                "top_left": "gcr648nj4c0r",
                "bottom_right": "tbn4zdz0b8hb"
              }
            ]
          },
          "geo_shape": {
            "type": "object",
            "description": "Polygon for `type: geo_shape`. Only this property and the companion\n`field` are used by that type; `field` is REQUIRED and must resolve to\na geo field (for example `_standard.geo.1`).\n\nThe only input is `points`, the polygon vertices. fylr builds the\nGeoJSON polygon itself and queries OpenSearch with a FIXED spatial\nrelation of `within` (the relation is not configurable, and a raw\nGeoJSON `{ type, coordinates }` body is NOT accepted here). The ring is\nclosed automatically by repeating the first vertex, so the first and\nlast vertex must not be duplicated in the request.\n\nRequires a license with geo support; otherwise the search is rejected.\n",
            "required": [
              "points"
            ],
            "additionalProperties": false,
            "properties": {
              "points": {
                "type": "array",
                "minItems": 3,
                "description": "Vertices of the polygon, each a `{ lat, lon }` point. At least 3\nvertices are required (fewer is rejected). Do not repeat the first\nvertex; the polygon is closed automatically.\n",
                "items": {
                  "$ref": "#/components/schemas/GeoPoint"
                }
              }
            },
            "examples": [
              {
                "points": [
                  {
                    "lat": 43.665014696873186,
                    "lon": 30.656803322464196
                  },
                  {
                    "lat": 45.829179968624345,
                    "lon": 39.444228256278876
                  },
                  {
                    "lat": 42.90364411679292,
                    "lon": 54.41512692671907
                  },
                  {
                    "lat": 32.48178389631096,
                    "lon": 54.371264285779894
                  },
                  {
                    "lat": 35.97404030325093,
                    "lon": 29.49485713607544
                  }
                ]
              }
            ]
          }
        }
      },
      "ExportApiList": {
        "type": "object",
        "description": "A page of the authenticated user's **exports**, as returned by\n`GET /api/v1/export`. `count` is the total number of exports\nmatching the filter, independent of `limit` / `offset`.\n",
        "required": [
          "limit",
          "offset",
          "count",
          "objects"
        ],
        "properties": {
          "limit": {
            "type": "integer",
            "format": "int64",
            "description": "The `limit` that was applied to this page."
          },
          "offset": {
            "type": "integer",
            "format": "int64",
            "description": "The `offset` that was applied to this page."
          },
          "count": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of exports matching the filter, ignoring\n`limit` / `offset`.\n"
          },
          "objects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportApi"
            },
            "description": "The exports on this page, newest first."
          }
        }
      },
      "EventBackgroundOrApi": {
        "description": "Response of `POST /event`. For a synchronous write this is the stored\nevent (`EventApi`). With `background=true` the body is the acknowledgement\nobject `{\"background\": \"ok\"}` and the event is saved asynchronously.\n",
        "oneOf": [
          {
            "$ref": "#/components/schemas/EventApi"
          },
          {
            "type": "object",
            "required": [
              "background"
            ],
            "properties": {
              "background": {
                "type": "string",
                "enum": [
                  "ok"
                ]
              }
            },
            "example": {
              "background": "ok"
            }
          }
        ]
      },
      "EventListBackgroundOrApi": {
        "description": "Response of `POST /event/list`. For a synchronous write this is the array\nof stored events (`EventApi`). With `background=true` the body is the\nacknowledgement object `{\"background\": \"ok\"}` and the events are saved\nasynchronously.\n",
        "oneOf": [
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventApi"
            }
          },
          {
            "type": "object",
            "required": [
              "background"
            ],
            "properties": {
              "background": {
                "type": "string",
                "enum": [
                  "ok"
                ]
              }
            },
            "example": {
              "background": "ok"
            }
          }
        ]
      },
      "ConfigParamBase": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "position": {
            "type": "number",
            "format": "int32",
            "minimum": 0,
            "description": "Position of the parameter in the output.\n"
          },
          "type": {
            "type": "string",
            "description": "type of the parameter"
          },
          "name": {
            "type": "string",
            "description": "name of the parameter as used in the API"
          }
        }
      },
      "ConfigParam": {
        "x-recursion": true,
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "bool": "#/components/schemas/ConfigParamBool",
            "email": "#/components/schemas/ConfigParamEmail",
            "file": "#/components/schemas/ConfigParamFile",
            "form": "#/components/schemas/ConfigParamForm",
            "int": "#/components/schemas/ConfigParamInt",
            "int-list": "#/components/schemas/ConfigParamIntList",
            "json": "#/components/schemas/ConfigParamJson",
            "license": "#/components/schemas/ConfigParamLicense",
            "location-select": "#/components/schemas/ConfigParamLocationSelect",
            "secret": "#/components/schemas/ConfigParamSecret",
            "select": "#/components/schemas/ConfigParamSelect",
            "string-list": "#/components/schemas/ConfigParamStringList",
            "string-list-sort": "#/components/schemas/ConfigParamStringListSort",
            "table": "#/components/schemas/ConfigParamTable",
            "tag-select": "#/components/schemas/ConfigParamTagSelect",
            "tagfilter-select": "#/components/schemas/ConfigParamTagfilterSelect",
            "text-l10n-multiline": "#/components/schemas/ConfigParamTextLocaMultiline",
            "text-l10n": "#/components/schemas/ConfigParamTextLoca",
            "text-multiline": "#/components/schemas/ConfigParamTextMultiline",
            "text": "#/components/schemas/ConfigParamText"
          }
        },
        "oneOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBool"
          },
          {
            "$ref": "#/components/schemas/ConfigParamEmail"
          },
          {
            "$ref": "#/components/schemas/ConfigParamFile"
          },
          {
            "$ref": "#/components/schemas/ConfigParamForm"
          },
          {
            "$ref": "#/components/schemas/ConfigParamInt"
          },
          {
            "$ref": "#/components/schemas/ConfigParamIntList"
          },
          {
            "$ref": "#/components/schemas/ConfigParamJson"
          },
          {
            "$ref": "#/components/schemas/ConfigParamLicense"
          },
          {
            "$ref": "#/components/schemas/ConfigParamLocationSelect"
          },
          {
            "$ref": "#/components/schemas/ConfigParamSecret"
          },
          {
            "$ref": "#/components/schemas/ConfigParamSelect"
          },
          {
            "$ref": "#/components/schemas/ConfigParamStringList"
          },
          {
            "$ref": "#/components/schemas/ConfigParamStringListSort"
          },
          {
            "$ref": "#/components/schemas/ConfigParamTable"
          },
          {
            "$ref": "#/components/schemas/ConfigParamTagSelect"
          },
          {
            "$ref": "#/components/schemas/ConfigParamTagfilterSelect"
          },
          {
            "$ref": "#/components/schemas/ConfigParamTextLoca"
          },
          {
            "$ref": "#/components/schemas/ConfigParamTextMultiline"
          },
          {
            "$ref": "#/components/schemas/ConfigParamText"
          }
        ]
      },
      "ConfigParamBool": {
        "description": "**bool** is a boolean",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "boolean"
              }
            }
          }
        ]
      },
      "ConfigParamEmail": {
        "description": "**email** is an email address consisting of loca part and domain name.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "boolean"
              }
            }
          }
        ]
      },
      "ConfigParamFile": {
        "description": "**file** is an eas file managed by fylr.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "object",
                "properties": {
                  "_id": {
                    "type": "integer",
                    "description": "An eas file id from fylr."
                  }
                }
              }
            }
          }
        ]
      },
      "ConfigParamInt": {
        "description": "**int** is an integer.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "integer"
              }
            }
          }
        ]
      },
      "ConfigParamIntList": {
        "description": "**int-list** is a plain list of integers, e.g. system object ids.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int64"
                }
              }
            }
          }
        ]
      },
      "ConfigParamLicense": {
        "description": "**license** is an license object.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "$ref": "#/components/schemas/License"
              }
            }
          }
        ]
      },
      "ConfigParamTable": {
        "description": "**table** is rows of parameters",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "object",
                "additionalProperties": true
              },
              "fields": {
                "type": "array",
                "description": "Items of this array are of schema ConfigParam",
                "items": {
                  "$ref": "#/components/schemas/ConfigParam"
                }
              }
            }
          }
        ]
      },
      "ConfigParamForm": {
        "description": "**form** is one row of nested parameters.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "object",
                "additionalProperties": true
              },
              "parameters": {
                "$ref": "#/components/schemas/ConfigParam"
              }
            }
          }
        ]
      },
      "ConfigParamJson": {
        "description": "The value of this type is and abritrary JSON object.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "plugin_type": {
                "type": "string",
                "description": "For some JSON, we support predefined schema."
              },
              "default": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        ]
      },
      "ConfigParamLocationSelect": {
        "description": "This presents a location select to the user.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "string",
                "description": "Location is a name of a configured location",
                "format": "location"
              }
            }
          }
        ]
      },
      "ConfigParamSecret": {
        "description": "**secret** is string which will be stored encrypted in the database, if `fylr.encryptionKey` is set.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "boolean"
              }
            }
          }
        ]
      },
      "ConfigParamSelect": {
        "description": "**select** is a choice select for one out of a list of options",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "options": {
                "type": "array",
                "description": "The list of options available for choice.",
                "items": {
                  "type": "string"
                }
              },
              "default": {
                "type": "string"
              }
            }
          }
        ]
      },
      "ConfigParamStringList": {
        "description": "**string-list** is a list of choices presented to the user.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "choices": {
                "type": "array",
                "description": "The list of options available for choice.",
                "items": {
                  "type": "string"
                }
              },
              "default": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        ]
      },
      "ConfigParamStringListSort": {
        "description": "**string-list-sort** is a list of sortable choices presented to the user.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "choices": {
                "type": "array",
                "description": "The list of options available for choice.",
                "items": {
                  "type": "string"
                }
              },
              "default": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        ]
      },
      "ConfigParamTagSelect": {
        "description": "**tag-select** is a list of tag ids, presented as a tag select to the user.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "array",
                "items": {
                  "type": "integer",
                  "format": "int64"
                }
              }
            }
          }
        ]
      },
      "ConfigParamTagfilterSelect": {
        "description": "This presents a tagfilter select to the user.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "properties": {
                  "any": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    }
                  },
                  "all": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    }
                  },
                  "not": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    }
                  }
                },
                "description": "Tagfilter is a map of sets of ids, as used in the fylr API.",
                "format": "tagfilter"
              }
            }
          }
        ]
      },
      "ConfigParamText": {
        "description": "**text** is a string",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "string"
              }
            }
          }
        ]
      },
      "ConfigParamTextMultiline": {
        "description": "**text-multiline** is like `text` but displayed in a mutliline form.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "string"
              }
            }
          }
        ]
      },
      "ConfigParamTextLoca": {
        "description": "**text-l10n** is a localized string",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "object",
                "properties": {
                  "de-DE": {
                    "type": "string"
                  },
                  "en-US": {
                    "type": "string"
                  }
                },
                "example": {
                  "de-DE": "Deutscher text",
                  "en-US": "English text"
                }
              }
            }
          }
        ]
      },
      "ConfigParamTextLocaMultiline": {
        "description": "**text-l10n-multinline** is like `text-l10n` but displayed in multiline form.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ConfigParamBase"
          },
          {
            "type": "object",
            "properties": {
              "default": {
                "type": "object",
                "properties": {
                  "de-DE": {
                    "type": "string"
                  },
                  "en-US": {
                    "type": "string"
                  }
                },
                "example": {
                  "de-DE": "Deutscher text",
                  "en-US": "English text"
                }
              }
            }
          }
        ]
      }
    }
  }
}