{
  "components": {
    "schemas": {
      "AddFieldRequest": {
        "properties": {
          "default": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Default"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional human-facing display name; free text.",
            "title": "Label"
          },
          "name": {
            "description": "Machine key: lowercase letters, digits and underscores, not starting with a digit. This is what workflows and CSV headers reference.",
            "title": "Name",
            "type": "string"
          },
          "required": {
            "default": false,
            "title": "Required",
            "type": "boolean"
          },
          "restrictions": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Restrictions"
          },
          "type": {
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "name",
          "type"
        ],
        "title": "AddFieldRequest",
        "type": "object"
      },
      "AddVolumeRequest": {
        "properties": {
          "add_to_queue": {
            "default": false,
            "description": "Also put the volume in the general write queue. Leave false for a volume that only homes particular collections.",
            "title": "Add To Queue",
            "type": "boolean"
          },
          "allocated_gb": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allocated Gb"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "name",
          "path"
        ],
        "title": "AddVolumeRequest",
        "type": "object"
      },
      "AiConfigResponse": {
        "properties": {
          "base_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Base Url"
          },
          "configured": {
            "title": "Configured",
            "type": "boolean"
          },
          "key_hint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Key Hint"
          },
          "model": {
            "title": "Model",
            "type": "string"
          },
          "provider": {
            "title": "Provider",
            "type": "string"
          },
          "source": {
            "title": "Source",
            "type": "string"
          }
        },
        "required": [
          "configured",
          "source",
          "model",
          "provider",
          "base_url",
          "key_hint"
        ],
        "title": "AiConfigResponse",
        "type": "object"
      },
      "AiConfigUpdate": {
        "properties": {
          "api_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Api Key"
          },
          "base_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Base Url"
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model"
          },
          "provider": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Provider"
          }
        },
        "title": "AiConfigUpdate",
        "type": "object"
      },
      "AiTokenUsageResponse": {
        "properties": {
          "bucket": {
            "title": "Bucket",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/TokenUsageBucketResponse"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "bucket",
          "items"
        ],
        "title": "AiTokenUsageResponse",
        "type": "object"
      },
      "AiUsageResponse": {
        "properties": {
          "by_model": {
            "items": {
              "$ref": "#/components/schemas/ModelUsageResponse"
            },
            "title": "By Model",
            "type": "array"
          },
          "total": {
            "$ref": "#/components/schemas/UsageTotalsResponse"
          }
        },
        "required": [
          "total",
          "by_model"
        ],
        "title": "AiUsageResponse",
        "type": "object"
      },
      "AssistantMessage": {
        "properties": {
          "content": {
            "title": "Content",
            "type": "string"
          },
          "role": {
            "const": "assistant",
            "default": "assistant",
            "title": "Role",
            "type": "string"
          }
        },
        "required": [
          "content"
        ],
        "title": "AssistantMessage",
        "type": "object"
      },
      "AuditBatchResponse": {
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "description": "import, delete, restore, purge or workflow.",
            "title": "Kind",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A workflow's name or an import's file.",
            "title": "Label"
          },
          "ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What started it, e.g. a workflow run's id.",
            "title": "Ref"
          }
        },
        "required": [
          "id",
          "kind",
          "created_at"
        ],
        "title": "AuditBatchResponse",
        "type": "object"
      },
      "AuditChange": {
        "properties": {
          "after": {
            "description": "The value after; null if unset.",
            "title": "After"
          },
          "before": {
            "description": "The value before; null if unset.",
            "title": "Before"
          },
          "deleted": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when this field has since been deleted: status (deleted = can still be restored, gone = permanently deleted), its id and, for a deleted one, the schema to restore it on and when it was deleted.",
            "title": "Deleted"
          },
          "dtype": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The field's type, when it still exists.",
            "title": "Dtype"
          },
          "field": {
            "description": "The field (record entries) or attribute (everything else) that changed, by name.",
            "title": "Field",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The field's display name now; null when it has since been renamed or deleted, or for a non-record entry.",
            "title": "Label"
          }
        },
        "required": [
          "field"
        ],
        "title": "AuditChange",
        "type": "object"
      },
      "AuditEventCountsResponse": {
        "properties": {
          "bucket": {
            "title": "Bucket",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/AuditEventPointResponse"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "bucket",
          "items"
        ],
        "title": "AuditEventCountsResponse",
        "type": "object"
      },
      "AuditEventPointResponse": {
        "properties": {
          "action": {
            "description": "One of: create, update, delete, purge.",
            "title": "Action",
            "type": "string"
          },
          "bucket": {
            "title": "Bucket",
            "type": "string"
          },
          "count": {
            "title": "Count",
            "type": "integer"
          },
          "entity_type": {
            "description": "One of: record, schema, field, dataset.",
            "title": "Entity Type",
            "type": "string"
          }
        },
        "required": [
          "bucket",
          "action",
          "entity_type",
          "count"
        ],
        "title": "AuditEventPointResponse",
        "type": "object"
      },
      "AuditEventResponse": {
        "properties": {
          "actor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who made it, as reported by the machine that made it; for a batch, who made its changes. Null when it was not recorded.",
            "title": "Actor"
          },
          "batch": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AuditBatchResponse"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the batch was, for kind=batch."
          },
          "count": {
            "description": "Changes in it that match the filters.",
            "title": "Count",
            "type": "integer"
          },
          "device": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "For a synced change, the device it came through (verified by the authority).",
            "title": "Device"
          },
          "entry": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AuditLogResponse"
              },
              {
                "type": "null"
              }
            ],
            "description": "The change itself, for kind=entry."
          },
          "id": {
            "description": "The entry's id, or the batch's.",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "description": "entry (a single change) or batch.",
            "title": "Kind",
            "type": "string"
          },
          "parts": {
            "description": "For a batch, what it holds by kind of thing and action. Its entries are listed at /audit/batches/{id}/entries.",
            "items": {
              "$ref": "#/components/schemas/AuditPart"
            },
            "title": "Parts",
            "type": "array"
          },
          "timestamp": {
            "description": "The latest change in it.",
            "format": "date-time",
            "title": "Timestamp",
            "type": "string"
          }
        },
        "required": [
          "id",
          "kind",
          "timestamp",
          "count"
        ],
        "title": "AuditEventResponse",
        "type": "object"
      },
      "AuditLogResponse": {
        "properties": {
          "action": {
            "description": "One of: create, update, delete, restore, purge.",
            "title": "Action",
            "type": "string"
          },
          "actor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who made the change, as reported by the machine that made it (the name chosen in the project, else the operating-system user). Not verified. Null for entries from before this was recorded.",
            "title": "Actor"
          },
          "changes": {
            "description": "What the entry changed, field by field, in schema order. A delete or purge lists the values that were lost; a restore lists nothing.",
            "items": {
              "$ref": "#/components/schemas/AuditChange"
            },
            "title": "Changes",
            "type": "array"
          },
          "device": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "For a synced change, the device it came through, as the authority stamped it from that device's token (verified). Null for a change made on the authority, not synced yet, or synced before this was kept.",
            "title": "Device"
          },
          "entity_id": {
            "title": "Entity Id",
            "type": "string"
          },
          "entity_type": {
            "description": "One of: record, schema, field, dataset, view.",
            "title": "Entity Type",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "new_data": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The thing after the change: whole for a create, identity and the changed values for an edit or restore (see `old_data`). Null on delete.",
            "title": "New Data"
          },
          "now": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AuditNow"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the record this entry is about is now, so a lost one can be told from one that was edited, deleted or purged."
          },
          "old_data": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The thing before the change. A delete has it whole; an edit or restore, which is stored as only what changed, has the thing's identity (id, name, label, where it sits) and the values it changed, so anything absent was not changed. A record's values are keyed by field id, so an entry survives a rename; `changes` has them by current name. Null on create.",
            "title": "Old Data"
          },
          "sync": {
            "description": "What became of this change when it was sent to the authority, if it did not go in as made: one row per clash, refusal or edit against a delete (kind, field_label, yours, theirs, base, theirs_actor, status, resolution, message, attempted, changes; the same rows as `/remote/conflicts`), open or settled. Empty for a change that went in as made, and when the project follows no authority.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Sync",
            "type": "array"
          },
          "timestamp": {
            "format": "date-time",
            "title": "Timestamp",
            "type": "string"
          }
        },
        "required": [
          "id",
          "action",
          "entity_type",
          "entity_id",
          "timestamp"
        ],
        "title": "AuditLogResponse",
        "type": "object"
      },
      "AuditNow": {
        "properties": {
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The collection it is in.",
            "title": "Collection"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deleted At"
          },
          "kind": {
            "description": "What the entry is about: record, collection, schema or field.",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its name now.",
            "title": "Name"
          },
          "ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to restore or purge it by: a record's or field's id, else its name.",
            "title": "Ref"
          },
          "schema_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its schema (for a field, the schema it belongs to); known even for a record that is gone for good.",
            "title": "Schema Name"
          },
          "status": {
            "description": "live (it exists), deleted (in Recently Deleted, restorable) or gone (permanently deleted).",
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "status"
        ],
        "title": "AuditNow",
        "type": "object"
      },
      "AuditPart": {
        "properties": {
          "action": {
            "title": "Action",
            "type": "string"
          },
          "count": {
            "title": "Count",
            "type": "integer"
          },
          "entity_type": {
            "title": "Entity Type",
            "type": "string"
          }
        },
        "required": [
          "entity_type",
          "action",
          "count"
        ],
        "title": "AuditPart",
        "type": "object"
      },
      "AuthorityResponse": {
        "properties": {
          "devices": {
            "description": "The devices that joined.",
            "items": {
              "$ref": "#/components/schemas/DeviceResponse"
            },
            "title": "Devices",
            "type": "array"
          },
          "fingerprint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "This authority's key's short code; null until it first invites.",
            "title": "Fingerprint"
          },
          "invites": {
            "description": "Invites not used yet and not expired.",
            "items": {
              "$ref": "#/components/schemas/InviteResponse"
            },
            "title": "Invites",
            "type": "array"
          },
          "library": {
            "default": "workflows",
            "description": "What devices allowed to publish may share through this server's library: off, workflows, or all (plugins too, which are code).",
            "title": "Library",
            "type": "string"
          },
          "serving": {
            "description": "This project accepts devices.",
            "title": "Serving",
            "type": "boolean"
          }
        },
        "required": [
          "serving",
          "fingerprint",
          "devices",
          "invites"
        ],
        "title": "AuthorityResponse",
        "type": "object"
      },
      "AuthorityUpdateRequest": {
        "properties": {
          "library": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "off, workflows or all: what the library takes.",
            "title": "Library"
          },
          "serving": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Accept devices, or stop accepting them.",
            "title": "Serving"
          }
        },
        "title": "AuthorityUpdateRequest",
        "type": "object"
      },
      "AutomationStatusResponse": {
        "properties": {
          "batch": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BatchResponse"
              },
              {
                "type": "null"
              }
            ],
            "description": "The current stretch of work with how many have succeeded and failed so far; null when nothing is waiting or running."
          },
          "cancelled": {
            "default": 0,
            "description": "How many runs the call just cancelled (stop only).",
            "title": "Cancelled",
            "type": "integer"
          },
          "paused": {
            "description": "True while automation is paused: triggers start nothing, waiting runs are not picked up, and manual runs are refused.",
            "title": "Paused",
            "type": "boolean"
          },
          "pending": {
            "description": "Runs waiting to start.",
            "title": "Pending",
            "type": "integer"
          },
          "running": {
            "description": "Runs in progress.",
            "title": "Running",
            "type": "integer"
          }
        },
        "required": [
          "paused",
          "pending",
          "running"
        ],
        "title": "AutomationStatusResponse",
        "type": "object"
      },
      "BatchResponse": {
        "properties": {
          "active": {
            "description": "Of those, waiting or running.",
            "title": "Active",
            "type": "integer"
          },
          "cancelled": {
            "description": "Of those, cancelled.",
            "title": "Cancelled",
            "type": "integer"
          },
          "completed": {
            "description": "Of those, finished successfully.",
            "title": "Completed",
            "type": "integer"
          },
          "failed": {
            "description": "Of those, failed.",
            "title": "Failed",
            "type": "integer"
          },
          "started_at": {
            "description": "When the earliest run in this stretch was queued.",
            "format": "date-time",
            "title": "Started At",
            "type": "string"
          },
          "total": {
            "description": "Every run in the current stretch of work: those finished since the queue was last empty, plus those still waiting or running.",
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "total",
          "active",
          "completed",
          "failed",
          "cancelled",
          "started_at"
        ],
        "title": "BatchResponse",
        "type": "object"
      },
      "BlockerResponse": {
        "properties": {
          "id": {
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "description": "collection, schema or record.",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "description": "What to call it: a name, or a record's name.",
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "id",
          "name"
        ],
        "title": "BlockerResponse",
        "type": "object"
      },
      "Body_bulk_delete_records_api_records_bulk_delete_post": {
        "properties": {
          "force": {
            "default": false,
            "title": "Force",
            "type": "boolean"
          },
          "ids": {
            "items": {
              "type": "string"
            },
            "title": "Ids",
            "type": "array"
          }
        },
        "required": [
          "ids"
        ],
        "title": "Body_bulk_delete_records_api_records_bulk_delete_post",
        "type": "object"
      },
      "Body_import_dump_api_restore_post": {
        "properties": {
          "file": {
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "type": "string"
          }
        },
        "required": [
          "file"
        ],
        "title": "Body_import_dump_api_restore_post",
        "type": "object"
      },
      "Body_upload_file_api_files_post": {
        "properties": {
          "file": {
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "type": "string"
          }
        },
        "required": [
          "file"
        ],
        "title": "Body_upload_file_api_files_post",
        "type": "object"
      },
      "Body_upload_plugin_api_plugins_upload_post": {
        "properties": {
          "file": {
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "type": "string"
          }
        },
        "required": [
          "file"
        ],
        "title": "Body_upload_plugin_api_plugins_upload_post",
        "type": "object"
      },
      "BuildResult": {
        "properties": {
          "log": {
            "title": "Log",
            "type": "string"
          },
          "success": {
            "title": "Success",
            "type": "boolean"
          }
        },
        "required": [
          "success",
          "log"
        ],
        "title": "BuildResult",
        "type": "object"
      },
      "ChatRequest": {
        "properties": {
          "messages": {
            "items": {
              "discriminator": {
                "mapping": {
                  "assistant": "#/components/schemas/AssistantMessage",
                  "tool_call": "#/components/schemas/ToolCallMessage",
                  "user": "#/components/schemas/UserMessage"
                },
                "propertyName": "role"
              },
              "oneOf": [
                {
                  "$ref": "#/components/schemas/UserMessage"
                },
                {
                  "$ref": "#/components/schemas/AssistantMessage"
                },
                {
                  "$ref": "#/components/schemas/ToolCallMessage"
                }
              ]
            },
            "title": "Messages",
            "type": "array"
          }
        },
        "required": [
          "messages"
        ],
        "title": "ChatRequest",
        "type": "object"
      },
      "CollectionFilesResponse": {
        "properties": {
          "bytes_here": {
            "description": "Their size.",
            "title": "Bytes Here",
            "type": "integer"
          },
          "chosen": {
            "description": "Set for this collection, rather than following the project's setting.",
            "title": "Chosen",
            "type": "boolean"
          },
          "files_here": {
            "description": "Files its records use that are here.",
            "title": "Files Here",
            "type": "integer"
          },
          "files_on_server": {
            "description": "Files its records use that are only on the server.",
            "title": "Files On Server",
            "type": "integer"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "mode": {
            "description": "keep: a copy stays on this computer (fetched in the background); opened: fetched when opened or exported.",
            "title": "Mode",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "mode",
          "chosen",
          "files_here",
          "bytes_here",
          "files_on_server"
        ],
        "title": "CollectionFilesResponse",
        "type": "object"
      },
      "CollectionModeRequest": {
        "properties": {
          "mode": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "keep, opened, or null to follow the project's setting.",
            "title": "Mode"
          }
        },
        "required": [
          "mode"
        ],
        "title": "CollectionModeRequest",
        "type": "object"
      },
      "CollectionStorageResponse": {
        "properties": {
          "bytes": {
            "description": "Total size of the files the catalog knows.",
            "title": "Bytes",
            "type": "integer"
          },
          "collection_id": {
            "title": "Collection Id",
            "type": "string"
          },
          "files": {
            "description": "Distinct files the collection's records use.",
            "title": "Files",
            "type": "integer"
          },
          "unlocated_files": {
            "description": "Files records use that the catalog doesn't place on any volume.",
            "title": "Unlocated Files",
            "type": "integer"
          },
          "unlocated_place": {
            "default": "missing",
            "description": "Where those are: `server` (this project follows one, so they are only there) or `missing`.",
            "title": "Unlocated Place",
            "type": "string"
          },
          "volumes": {
            "description": "Each volume that holds some of them, largest first.",
            "items": {
              "$ref": "#/components/schemas/CollectionVolumeShareResponse"
            },
            "title": "Volumes",
            "type": "array"
          }
        },
        "required": [
          "collection_id",
          "files",
          "bytes",
          "volumes",
          "unlocated_files"
        ],
        "title": "CollectionStorageResponse",
        "type": "object"
      },
      "CollectionUseResponse": {
        "properties": {
          "id": {
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null if the collection no longer exists.",
            "title": "Name"
          },
          "records": {
            "description": "Records in that collection that use the file.",
            "title": "Records",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "name",
          "records"
        ],
        "title": "CollectionUseResponse",
        "type": "object"
      },
      "CollectionVolumeShareResponse": {
        "properties": {
          "available": {
            "description": "Whether the volume can be read right now.",
            "title": "Available",
            "type": "boolean"
          },
          "bytes": {
            "title": "Bytes",
            "type": "integer"
          },
          "files": {
            "description": "Files of the collection on this volume.",
            "title": "Files",
            "type": "integer"
          },
          "shared_files": {
            "description": "Of those, files another collection uses too (moving one affects both).",
            "title": "Shared Files",
            "type": "integer"
          },
          "state": {
            "description": "The volume's state now: online, offline, wrong_drive, readonly or retired.",
            "title": "State",
            "type": "string"
          },
          "volume": {
            "title": "Volume",
            "type": "string"
          }
        },
        "required": [
          "volume",
          "files",
          "bytes",
          "shared_files",
          "state",
          "available"
        ],
        "title": "CollectionVolumeShareResponse",
        "type": "object"
      },
      "CommandLineResponse": {
        "properties": {
          "available": {
            "description": "Whether this is the desktop app's civex, the only one this applies to (a uv, pipx or pip install is already a command).",
            "title": "Available",
            "type": "boolean"
          },
          "note": {
            "description": "What is still to do, or why it can't be done; blank if nothing.",
            "title": "Note",
            "type": "string"
          },
          "on_path": {
            "description": "Whether a new terminal finds this civex as `civex`.",
            "title": "On Path",
            "type": "boolean"
          },
          "shadowed_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Another civex a terminal would find first, if there is one.",
            "title": "Shadowed By"
          },
          "where": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The folder put on PATH (Windows) or the link made (macOS, Linux).",
            "title": "Where"
          }
        },
        "required": [
          "available",
          "on_path",
          "where",
          "shadowed_by",
          "note"
        ],
        "title": "CommandLineResponse",
        "type": "object"
      },
      "ConflictResponse": {
        "properties": {
          "also_saved": {
            "description": "Other values the same edit set that did go in: field_label, value.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Also Saved",
            "type": "array"
          },
          "attempted": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "For a refused change or an edit that met a delete: what was tried (create, update or delete).",
            "title": "Attempted"
          },
          "base": {
            "description": "What the value was before either side changed it.",
            "title": "Base"
          },
          "changes": {
            "description": "The fields that attempt set, for showing it on the record: field_id, field_name, field_label, dtype, before, after and current.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Changes",
            "type": "array"
          },
          "created_at": {
            "title": "Created At",
            "type": "string"
          },
          "current": {
            "description": "The value on the record now.",
            "title": "Current"
          },
          "dataset_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its collection.",
            "title": "Dataset Name"
          },
          "device_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Device Name"
          },
          "dtype": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The field's type.",
            "title": "Dtype"
          },
          "entity_id": {
            "title": "Entity Id",
            "type": "string"
          },
          "entity_type": {
            "title": "Entity Type",
            "type": "string"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          },
          "field_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The field's label now; null if the field is gone.",
            "title": "Field Label"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "description": "conflict, rejected or edit_vs_delete.",
            "title": "Kind",
            "type": "string"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message"
          },
          "record_deleted": {
            "default": false,
            "description": "The record is deleted (restore it first).",
            "title": "Record Deleted",
            "type": "boolean"
          },
          "record_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The record's name as it is now (records only).",
            "title": "Record Name"
          },
          "resolution": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "mine, theirs, value, edited, delete or retry, once resolved.",
            "title": "Resolution"
          },
          "resolved_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resolved At"
          },
          "schema_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its schema.",
            "title": "Schema Name"
          },
          "sits_under": {
            "description": "For a refused record that sits under deleted records here: those records (id, schema_name, name), topmost first. `restore_above` brings them back and sends the record again.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Sits Under",
            "type": "array"
          },
          "stale": {
            "default": false,
            "description": "The record's value is no longer the one that stayed: it changed again since, so putting yours back would overwrite something newer.",
            "title": "Stale",
            "type": "boolean"
          },
          "status": {
            "description": "open or resolved.",
            "title": "Status",
            "type": "string"
          },
          "takes": {
            "description": "What this can be settled with: theirs, mine, value, delete, retry (`edited` is also accepted for a clash, but is not a choice to offer).",
            "items": {
              "type": "string"
            },
            "title": "Takes",
            "type": "array"
          },
          "theirs": {
            "description": "The value the authority kept.",
            "title": "Theirs"
          },
          "theirs_actor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who wrote the value that stayed.",
            "title": "Theirs Actor"
          },
          "theirs_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When they wrote it.",
            "title": "Theirs At"
          },
          "theirs_device": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The device their change came through (verified by the authority), when it came through one.",
            "title": "Theirs Device"
          },
          "yours": {
            "description": "The value this device set.",
            "title": "Yours"
          }
        },
        "required": [
          "id",
          "kind",
          "entity_type",
          "entity_id",
          "field",
          "yours",
          "theirs",
          "device_name",
          "message",
          "status",
          "created_at",
          "resolved_at",
          "resolution"
        ],
        "title": "ConflictResponse",
        "type": "object"
      },
      "ConnectionCheckResponse": {
        "properties": {
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why not, in plain words, when ok is false.",
            "title": "Error"
          },
          "ok": {
            "description": "Whether a connection was made.",
            "title": "Ok",
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "title": "ConnectionCheckResponse",
        "type": "object"
      },
      "ContainerFileSaveRequest": {
        "properties": {
          "content": {
            "title": "Content",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path",
          "content"
        ],
        "title": "ContainerFileSaveRequest",
        "type": "object"
      },
      "ContainerPluginDetail": {
        "properties": {
          "files": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Files",
            "type": "object"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "files"
        ],
        "title": "ContainerPluginDetail",
        "type": "object"
      },
      "ContainerPluginInfo": {
        "properties": {
          "files": {
            "items": {
              "type": "string"
            },
            "title": "Files",
            "type": "array"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "files"
        ],
        "title": "ContainerPluginInfo",
        "type": "object"
      },
      "CreateDatasetRequest": {
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "schemas": {
            "description": "Names of the schemas the collection is for. A child schema's parent schema must be listed too.",
            "items": {
              "type": "string"
            },
            "title": "Schemas",
            "type": "array"
          },
          "scope": {
            "default": "local",
            "description": "'local' (default) or 'global' -- see the collection's `scope`.",
            "title": "Scope",
            "type": "string"
          },
          "timezone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "IANA timezone for datetime values in this collection. Omit or null to leave unset.",
            "title": "Timezone"
          }
        },
        "required": [
          "name"
        ],
        "title": "CreateDatasetRequest",
        "type": "object"
      },
      "CreateExportDefinitionRequest": {
        "properties": {
          "fields": {
            "description": "File fields to export; empty means every file field.",
            "items": {
              "type": "string"
            },
            "title": "Fields",
            "type": "array"
          },
          "files_layout": {
            "default": "tree",
            "description": "'tree': a folder per record above each file; 'grouped': the records that hold the files share one folder named for their kind (Encounter/Recording/Selections/...); 'flat': every file in one folder.",
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Files Layout",
            "type": "string"
          },
          "filter_tree": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A filter on the records that hold the files; needs 'holder'.",
            "title": "Filter Tree"
          },
          "holder": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The kind of record that holds the files: the schema itself or a kind beneath it. Omit for any kind beneath.",
            "title": "Holder"
          },
          "include_files": {
            "default": true,
            "description": "False makes the export tables alone.",
            "title": "Include Files",
            "type": "boolean"
          },
          "name": {
            "description": "What the export is called, in your own words.",
            "title": "Name",
            "type": "string"
          },
          "tables": {
            "description": "Also make these tables.",
            "items": {
              "$ref": "#/components/schemas/TableRequest"
            },
            "title": "Tables",
            "type": "array"
          }
        },
        "required": [
          "name"
        ],
        "title": "CreateExportDefinitionRequest",
        "type": "object"
      },
      "CreateFolderRequest": {
        "properties": {
          "name": {
            "description": "Name of the new folder (no slashes).",
            "title": "Name",
            "type": "string"
          },
          "parent": {
            "description": "Absolute path of the folder to create it in.",
            "title": "Parent",
            "type": "string"
          }
        },
        "required": [
          "parent",
          "name"
        ],
        "title": "CreateFolderRequest",
        "type": "object"
      },
      "CreateFolderResponse": {
        "properties": {
          "path": {
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "title": "CreateFolderResponse",
        "type": "object"
      },
      "CreateRecordRequest": {
        "properties": {
          "data": {
            "additionalProperties": true,
            "default": {},
            "title": "Data",
            "type": "object"
          },
          "parent_record_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Record Id"
          },
          "schema_name": {
            "title": "Schema Name",
            "type": "string"
          }
        },
        "required": [
          "schema_name"
        ],
        "title": "CreateRecordRequest",
        "type": "object"
      },
      "CreateSchemaRequest": {
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "fields": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/AddFieldRequest"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fields"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional human-facing display name; free text.",
            "title": "Label"
          },
          "name": {
            "description": "Machine key: lowercase letters, digits and underscores, not starting with a digit.",
            "title": "Name",
            "type": "string"
          },
          "parent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent"
          }
        },
        "required": [
          "name"
        ],
        "title": "CreateSchemaRequest",
        "type": "object"
      },
      "CreateViewRequest": {
        "properties": {
          "columns": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Base schema field names to show, in order. May also include single-hop reference-field joins as 'ref_field.target_field'.",
            "title": "Columns"
          },
          "files_layout": {
            "default": "tree",
            "description": "How the view's files are arranged when exported: 'tree' (a folder per record above each file) or 'flat' (all in one folder).",
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Files Layout",
            "type": "string"
          },
          "filter_tree": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "AND/OR filter tree, same shape as the records 'filter' query parameter (conditions may name an ancestor or descendant schema).",
            "title": "Filter Tree"
          },
          "name": {
            "description": "What the view is called, in your own words -- spaces, capitals and punctuation are fine. Only '/', '\\' and control characters are refused. Unique per schema.",
            "title": "Name",
            "type": "string"
          },
          "sort": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ordered list of {field, direction} entries; direction is 'asc' or 'desc'.",
            "title": "Sort"
          }
        },
        "required": [
          "name"
        ],
        "title": "CreateViewRequest",
        "type": "object"
      },
      "DBStatusResponse": {
        "properties": {
          "ok": {
            "default": true,
            "title": "Ok",
            "type": "boolean"
          }
        },
        "title": "DBStatusResponse",
        "type": "object"
      },
      "DatabaseSummaryResponse": {
        "properties": {
          "dialect": {
            "description": "'sqlite' or 'postgresql'.",
            "title": "Dialect",
            "type": "string"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why not, when unreachable.",
            "title": "Error"
          },
          "label": {
            "description": "'SQLite file', 'Docker PostgreSQL' or 'PostgreSQL server'.",
            "title": "Label",
            "type": "string"
          },
          "location": {
            "description": "Where it is, with any password hidden.",
            "title": "Location",
            "type": "string"
          },
          "reachable": {
            "description": "Whether it could be read.",
            "title": "Reachable",
            "type": "boolean"
          },
          "records": {
            "description": "Number of records.",
            "title": "Records",
            "type": "integer"
          },
          "rows": {
            "description": "Rows across every table.",
            "title": "Rows",
            "type": "integer"
          },
          "size_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "On-disk size, when known.",
            "title": "Size Bytes"
          }
        },
        "required": [
          "label",
          "dialect",
          "location",
          "reachable",
          "records",
          "rows"
        ],
        "title": "DatabaseSummaryResponse",
        "type": "object"
      },
      "DatasetResponse": {
        "properties": {
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When this collection was soft-deleted. Null means live.",
            "title": "Deleted At"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "record_count": {
            "title": "Record Count",
            "type": "integer"
          },
          "schemas": {
            "description": "Names of the schemas this collection is for. Records in it can only be of these schemas.",
            "items": {
              "type": "string"
            },
            "title": "Schemas",
            "type": "array"
          },
          "scope": {
            "default": "local",
            "description": "Who may reference this collection's records: 'local' (only records in this collection) or 'global' (records in any collection).",
            "title": "Scope",
            "type": "string"
          },
          "timezone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "IANA timezone (e.g. 'America/Chicago') that datetime values in this collection are read and shown in. Null means unset: offset-less input is read as UTC and the UI uses the viewer's own zone. A datetime field's own `timezone` restriction overrides this.",
            "title": "Timezone"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "record_count"
        ],
        "title": "DatasetResponse",
        "type": "object"
      },
      "DbStatusResponse": {
        "properties": {
          "dialect": {
            "title": "Dialect",
            "type": "string"
          },
          "docker": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DockerStatusResponse"
              },
              {
                "type": "null"
              }
            ]
          },
          "docker_managed": {
            "title": "Docker Managed",
            "type": "boolean"
          },
          "migration": {
            "$ref": "#/components/schemas/MigrationStatusResponse"
          },
          "url": {
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url",
          "dialect",
          "docker_managed",
          "migration",
          "docker"
        ],
        "title": "DbStatusResponse",
        "type": "object"
      },
      "DeleteJobsRequest": {
        "properties": {
          "filter": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Instead of ids: delete every run this filter matches (the same filter tree as GET /jobs, at most 1000 runs).",
            "title": "Filter"
          },
          "ids": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "maxItems": 1000,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ids of the runs to delete.",
            "title": "Ids"
          }
        },
        "title": "DeleteJobsRequest",
        "type": "object"
      },
      "DeleteJobsResponse": {
        "properties": {
          "deleted": {
            "description": "How many runs were deleted.",
            "title": "Deleted",
            "type": "integer"
          }
        },
        "required": [
          "deleted"
        ],
        "title": "DeleteJobsResponse",
        "type": "object"
      },
      "DeletedFieldValue": {
        "properties": {
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the field was deleted.",
            "title": "Deleted At"
          },
          "dtype": {
            "title": "Dtype",
            "type": "string"
          },
          "id": {
            "description": "The deleted field's id.",
            "title": "Id",
            "type": "string"
          },
          "label": {
            "description": "Its display name.",
            "title": "Label",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "schema_name": {
            "description": "The schema it was defined on, which is where to restore it.",
            "title": "Schema Name",
            "type": "string"
          },
          "value": {
            "description": "What this record still holds for it; back in `data` once the field is restored.",
            "title": "Value"
          }
        },
        "required": [
          "id",
          "name",
          "label",
          "dtype",
          "schema_name",
          "value"
        ],
        "title": "DeletedFieldValue",
        "type": "object"
      },
      "DevicePublishRequest": {
        "properties": {
          "allowed": {
            "description": "May it publish to the library.",
            "title": "Allowed",
            "type": "boolean"
          }
        },
        "required": [
          "allowed"
        ],
        "title": "DevicePublishRequest",
        "type": "object"
      },
      "DeviceResponse": {
        "properties": {
          "created_at": {
            "description": "When it joined.",
            "title": "Created At",
            "type": "string"
          },
          "fingerprint": {
            "description": "Its key's short code, as `civex sync device list` shows it.",
            "title": "Fingerprint",
            "type": "string"
          },
          "last_seen_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it last signed in; null if never.",
            "title": "Last Seen At"
          },
          "may_publish": {
            "default": false,
            "description": "It may publish workflows (and plugins, if taken) to the library.",
            "title": "May Publish",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "revoked": {
            "description": "It can no longer sign in.",
            "title": "Revoked",
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "fingerprint",
          "created_at",
          "last_seen_at",
          "revoked"
        ],
        "title": "DeviceResponse",
        "type": "object"
      },
      "DirectoryEntryResponse": {
        "properties": {
          "name": {
            "title": "Name",
            "type": "string"
          },
          "path": {
            "description": "Absolute path of the folder.",
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "name",
          "path"
        ],
        "title": "DirectoryEntryResponse",
        "type": "object"
      },
      "DirectoryListingResponse": {
        "properties": {
          "entries": {
            "description": "The folders directly inside it (never files).",
            "items": {
              "$ref": "#/components/schemas/DirectoryEntryResponse"
            },
            "title": "Entries",
            "type": "array"
          },
          "hint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why a drive might be missing from `locations`, where the platform has a known reason (for example a Windows drive not yet mounted under WSL).",
            "title": "Hint"
          },
          "locations": {
            "description": "Places to start browsing from: the project, home and mounted drives.",
            "items": {
              "$ref": "#/components/schemas/StorageLocationResponse"
            },
            "title": "Locations",
            "type": "array"
          },
          "parent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its parent folder; null at the top.",
            "title": "Parent"
          },
          "path": {
            "description": "The folder that was listed, as an absolute path.",
            "title": "Path",
            "type": "string"
          },
          "truncated": {
            "description": "True if there were more folders than are shown.",
            "title": "Truncated",
            "type": "boolean"
          }
        },
        "required": [
          "path",
          "parent",
          "entries",
          "truncated",
          "locations"
        ],
        "title": "DirectoryListingResponse",
        "type": "object"
      },
      "DockerStatusResponse": {
        "properties": {
          "exists": {
            "title": "Exists",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "running": {
            "title": "Running",
            "type": "boolean"
          },
          "volume_exists": {
            "title": "Volume Exists",
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "exists",
          "running",
          "volume_exists"
        ],
        "title": "DockerStatusResponse",
        "type": "object"
      },
      "DurationHistogramBinResponse": {
        "properties": {
          "count": {
            "title": "Count",
            "type": "integer"
          },
          "label": {
            "description": "Duration bucket, e.g. '1-2s' or '30s+'.",
            "title": "Label",
            "type": "string"
          }
        },
        "required": [
          "label",
          "count"
        ],
        "title": "DurationHistogramBinResponse",
        "type": "object"
      },
      "DurationPercentileMarkerResponse": {
        "properties": {
          "bin_label": {
            "description": "Which histogram bucket this percentile falls in.",
            "title": "Bin Label",
            "type": "string"
          },
          "label": {
            "description": "e.g. 'p50', 'p90', 'p99'.",
            "title": "Label",
            "type": "string"
          }
        },
        "required": [
          "label",
          "bin_label"
        ],
        "title": "DurationPercentileMarkerResponse",
        "type": "object"
      },
      "ExportDefinitionResponse": {
        "properties": {
          "fields": {
            "description": "The file fields exported; empty means every file field.",
            "items": {
              "type": "string"
            },
            "title": "Fields",
            "type": "array"
          },
          "files_layout": {
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Files Layout",
            "type": "string"
          },
          "filter_tree": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A filter on the records that hold the files (same shape as the records 'filter' parameter).",
            "title": "Filter Tree"
          },
          "holder": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The kind of record that holds the files; null means any kind beneath the schema.",
            "title": "Holder"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "include_files": {
            "default": true,
            "description": "False: the export is tables alone.",
            "title": "Include Files",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "schema_id": {
            "title": "Schema Id",
            "type": "string"
          },
          "schema_name": {
            "description": "The schema the export is saved with.",
            "title": "Schema Name",
            "type": "string"
          },
          "tables": {
            "description": "The tables made beside the files.",
            "items": {
              "$ref": "#/components/schemas/TableRequest"
            },
            "title": "Tables",
            "type": "array"
          }
        },
        "required": [
          "id",
          "schema_id",
          "schema_name",
          "name",
          "fields",
          "files_layout"
        ],
        "title": "ExportDefinitionResponse",
        "type": "object"
      },
      "FailureGroupResponse": {
        "properties": {
          "count": {
            "description": "How many runs failed this way.",
            "title": "Count",
            "type": "integer"
          },
          "kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The failure type, such as timeout.",
            "title": "Kind"
          },
          "last_at": {
            "description": "When one last did.",
            "format": "date-time",
            "title": "Last At",
            "type": "string"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The failure's own message.",
            "title": "Message"
          },
          "step": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The step that failed.",
            "title": "Step"
          },
          "workflow": {
            "title": "Workflow",
            "type": "string"
          }
        },
        "required": [
          "workflow",
          "kind",
          "step",
          "message",
          "count",
          "last_at"
        ],
        "title": "FailureGroupResponse",
        "type": "object"
      },
      "FieldKindResponse": {
        "properties": {
          "description": {
            "description": "What the kind is for.",
            "title": "Description",
            "type": "string"
          },
          "focus": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Restriction key the editor should lead with, if any.",
            "title": "Focus"
          },
          "key": {
            "description": "Stable identifier of the kind.",
            "title": "Key",
            "type": "string"
          },
          "label": {
            "description": "Name shown in the field-kind picker.",
            "title": "Label",
            "type": "string"
          },
          "type": {
            "description": "The field type a field of this kind is created as.",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "key",
          "label",
          "type",
          "description",
          "focus"
        ],
        "title": "FieldKindResponse",
        "type": "object"
      },
      "FieldResponse": {
        "properties": {
          "default": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Default"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Human-facing display name. Null means none was set \u2014 render the name title-cased instead.",
            "title": "Label"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "required": {
            "title": "Required",
            "type": "boolean"
          },
          "restrictions": {
            "additionalProperties": true,
            "default": {},
            "title": "Restrictions",
            "type": "object"
          },
          "type": {
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "required"
        ],
        "title": "FieldResponse",
        "type": "object"
      },
      "FieldTypeDescriptorResponse": {
        "properties": {
          "description": {
            "description": "What the type is for.",
            "title": "Description",
            "type": "string"
          },
          "entry_hint": {
            "description": "One line of guidance shown beside the input on the record page.",
            "title": "Entry Hint",
            "type": "string"
          },
          "example": {
            "description": "An example value as a person would type it.",
            "title": "Example",
            "type": "string"
          },
          "label": {
            "description": "Plain-language name of the type.",
            "title": "Label",
            "type": "string"
          },
          "restrictions": {
            "description": "The rules a field of this type can carry, in display order.",
            "items": {
              "$ref": "#/components/schemas/RestrictionDescriptorResponse"
            },
            "title": "Restrictions",
            "type": "array"
          },
          "stored_as": {
            "description": "How a value is held, in plain language.",
            "title": "Stored As",
            "type": "string"
          },
          "supports_default": {
            "description": "Whether a default value can be set when creating the field.",
            "title": "Supports Default",
            "type": "boolean"
          },
          "type": {
            "description": "The field type name, as used in `type`.",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "type",
          "label",
          "description",
          "stored_as",
          "entry_hint",
          "example",
          "restrictions",
          "supports_default"
        ],
        "title": "FieldTypeDescriptorResponse",
        "type": "object"
      },
      "FieldTypesResponse": {
        "properties": {
          "kinds": {
            "description": "The 'what kind of data is this?' picker, in display order.",
            "items": {
              "$ref": "#/components/schemas/FieldKindResponse"
            },
            "title": "Kinds",
            "type": "array"
          },
          "types": {
            "description": "Every field type, with the rules each can carry.",
            "items": {
              "$ref": "#/components/schemas/FieldTypeDescriptorResponse"
            },
            "title": "Types",
            "type": "array"
          }
        },
        "required": [
          "types",
          "kinds"
        ],
        "title": "FieldTypesResponse",
        "type": "object"
      },
      "FileCopyResponse": {
        "properties": {
          "network": {
            "description": "The volume is on a network drive.",
            "title": "Network",
            "type": "boolean"
          },
          "path": {
            "description": "Where the object is, or would be, on that volume.",
            "title": "Path",
            "type": "string"
          },
          "present": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "True if it is there; null if it is recorded there but the volume can't be checked now.",
            "title": "Present"
          },
          "state": {
            "description": "The volume's state: online, offline, wrong_drive, readonly or retired.",
            "title": "State",
            "type": "string"
          },
          "volume": {
            "title": "Volume",
            "type": "string"
          }
        },
        "required": [
          "volume",
          "path",
          "present",
          "state",
          "network"
        ],
        "title": "FileCopyResponse",
        "type": "object"
      },
      "FileExportRequest": {
        "properties": {
          "allow_partial": {
            "default": false,
            "description": "Go ahead without files that can't be reached. Without it, a selection with unreachable files answers 409 and builds nothing.",
            "title": "Allow Partial",
            "type": "boolean"
          },
          "base": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix) that paths start below; defaults to 'within'.",
            "title": "Base"
          },
          "below": {
            "default": false,
            "description": "Also take the files of every record beneath each selected one (the selected encounters, and everything inside them). Without it, only the selected records' own files.",
            "title": "Below",
            "type": "boolean"
          },
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only this collection.",
            "title": "Collection"
          },
          "dest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Advanced: a folder to build in, empty or an earlier export, instead of civex's own exports folder. Overrides 'name' and 'volume'. For 'link' it must be on the drive holding the files.",
            "title": "Dest"
          },
          "export": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "An export saved with a schema, as 'schema/name': its kind of record, file fields, filter, layout and tables become the selection, run in 'collection' and/or within the record 'within'. Sending 'layout', 'tables' or 'files' overrides what it has.",
            "title": "Export"
          },
          "fields": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these file fields; omit for every one.",
            "title": "Fields"
          },
          "files": {
            "default": true,
            "description": "False takes the tables alone, with no files (needs 'tables').",
            "title": "Files",
            "type": "boolean"
          },
          "filter": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A filter tree, as for listing records.",
            "title": "Filter"
          },
          "kinds": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of these kinds (schema names), when 'schema_name' is not given: how a preview of an export that takes any kind beneath a schema stays within that schema's own tree.",
            "title": "Kinds"
          },
          "layout": {
            "default": "tree",
            "description": "'tree' puts each file in a folder per record above it; 'grouped' gathers the files of the records that hold them into one folder named for their kind (Encounter/Recording/Selections/...); 'flat' puts every file in one folder. Names that clash in a shared folder are told apart by the record that owns each. A saved view carries its own (files_layout); sending this with 'view' overrides it.",
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Layout",
            "type": "string"
          },
          "mode": {
            "default": "link",
            "description": "'link' makes hard links in a folder on the drive that holds the files: no copying, no extra space, and refused (409 'files_scattered') when the files are on more than one drive. 'copy' makes real copies on one drive ('volume'), wherever the files are.",
            "enum": [
              "link",
              "copy"
            ],
            "title": "Mode",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Names the folder: <where>/exports/<name>. The same name reuses the same folder.",
            "title": "Name"
          },
          "open": {
            "default": false,
            "description": "Show the folder in the file manager, if the request came from the server's own machine.",
            "title": "Open",
            "type": "boolean"
          },
          "record_ids": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exactly these records (the rows ticked in a list); the other selectors are then ignored.",
            "title": "Record Ids"
          },
          "schema_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of this schema.",
            "title": "Schema Name"
          },
          "search": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Full-text search.",
            "title": "Search"
          },
          "sort": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The order of the records, and so of the rows of a table: [{'field': name, 'direction': 'asc'|'desc'}, ...].",
            "title": "Sort"
          },
          "tables": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TableRequest"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Also make these tables. Each file column in one says where that file is in the export. Sending it overrides the tables a saved 'export' has; an empty list removes them.",
            "title": "Tables"
          },
          "view": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A saved view as 'schema/view': its filter, its file columns and its layout become the selection ('collection' and 'within' still narrow it).",
            "title": "View"
          },
          "volume": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "For 'copy': the drive to copy onto (a volume name); the project folder if omitted. Ignored for 'link', which goes where the files are.",
            "title": "Volume"
          },
          "where": {
            "description": "'field=value' terms.",
            "items": {
              "type": "string"
            },
            "title": "Where",
            "type": "array"
          },
          "with_within": {
            "default": false,
            "description": "With `within` and `schema_name`: also the files of the `within` record itself (a list of what a record contains, taking the record's own files too).",
            "title": "With Within",
            "type": "boolean"
          },
          "within": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix): its files and those of everything beneath it. Paths start below it. With 'schema_name', only that schema's records under it.",
            "title": "Within"
          }
        },
        "title": "FileExportRequest",
        "type": "object"
      },
      "FileGatherRequest": {
        "properties": {
          "base": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix) that paths start below; defaults to 'within'.",
            "title": "Base"
          },
          "below": {
            "default": false,
            "description": "Also take the files of every record beneath each selected one (the selected encounters, and everything inside them). Without it, only the selected records' own files.",
            "title": "Below",
            "type": "boolean"
          },
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only this collection.",
            "title": "Collection"
          },
          "export": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "An export saved with a schema, as 'schema/name': its kind of record, file fields, filter, layout and tables become the selection, run in 'collection' and/or within the record 'within'. Sending 'layout', 'tables' or 'files' overrides what it has.",
            "title": "Export"
          },
          "fields": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these file fields; omit for every one.",
            "title": "Fields"
          },
          "files": {
            "default": true,
            "description": "False takes the tables alone, with no files (needs 'tables').",
            "title": "Files",
            "type": "boolean"
          },
          "filter": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A filter tree, as for listing records.",
            "title": "Filter"
          },
          "include_shared": {
            "default": false,
            "description": "Also move files that records not picked use (they move for those records too). By default those stay where they are.",
            "title": "Include Shared",
            "type": "boolean"
          },
          "kinds": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of these kinds (schema names), when 'schema_name' is not given: how a preview of an export that takes any kind beneath a schema stays within that schema's own tree.",
            "title": "Kinds"
          },
          "layout": {
            "default": "tree",
            "description": "'tree' puts each file in a folder per record above it; 'grouped' gathers the files of the records that hold them into one folder named for their kind (Encounter/Recording/Selections/...); 'flat' puts every file in one folder. Names that clash in a shared folder are told apart by the record that owns each. A saved view carries its own (files_layout); sending this with 'view' overrides it.",
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Layout",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files whose name, or whose record's name, contains this.",
            "title": "Name"
          },
          "place": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files in this place: a drive's name, `server` (only on the server), `missing`, or the groups `here` (on a drive that can be read now) and `unreachable` (on one that can't).",
            "title": "Place"
          },
          "record_ids": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exactly these records (the rows ticked in a list); the other selectors are then ignored.",
            "title": "Record Ids"
          },
          "schema_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of this schema.",
            "title": "Schema Name"
          },
          "search": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Full-text search.",
            "title": "Search"
          },
          "shas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "maxItems": 100000,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these files (by content hash), e.g. the ticked rows: each with every use of it in the selection. Records outside the selection that use the same file are not picked.",
            "title": "Shas"
          },
          "sort": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The order of the records, and so of the rows of a table: [{'field': name, 'direction': 'asc'|'desc'}, ...].",
            "title": "Sort"
          },
          "tables": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TableRequest"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Also make these tables. Each file column in one says where that file is in the export. Sending it overrides the tables a saved 'export' has; an empty list removes them.",
            "title": "Tables"
          },
          "used_by": {
            "anyOf": [
              {
                "items": {
                  "type": "integer"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files used by exactly one of these numbers of live records (anywhere, not only in the selection).",
            "title": "Used By"
          },
          "view": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A saved view as 'schema/view': its filter, its file columns and its layout become the selection ('collection' and 'within' still narrow it).",
            "title": "View"
          },
          "volume": {
            "description": "The drive (volume name) to gather the selection's files onto. Only the files in the selection move, not the rest of their collections.",
            "title": "Volume",
            "type": "string"
          },
          "where": {
            "description": "'field=value' terms.",
            "items": {
              "type": "string"
            },
            "title": "Where",
            "type": "array"
          },
          "with_within": {
            "default": false,
            "description": "With `within` and `schema_name`: also the files of the `within` record itself (a list of what a record contains, taking the record's own files too).",
            "title": "With Within",
            "type": "boolean"
          },
          "within": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix): its files and those of everything beneath it. Paths start below it. With 'schema_name', only that schema's records under it.",
            "title": "Within"
          }
        },
        "required": [
          "volume"
        ],
        "title": "FileGatherRequest",
        "type": "object"
      },
      "FileInfoResponse": {
        "properties": {
          "collections": {
            "items": {
              "$ref": "#/components/schemas/CollectionUseResponse"
            },
            "title": "Collections",
            "type": "array"
          },
          "copies": {
            "description": "Every place the content is, or is recorded to be.",
            "items": {
              "$ref": "#/components/schemas/FileCopyResponse"
            },
            "title": "Copies",
            "type": "array"
          },
          "deleted_records": {
            "default": 0,
            "description": "Deleted records that still reference it: they keep it while they can be restored, but don't count as using it.",
            "title": "Deleted Records",
            "type": "integer"
          },
          "jobs": {
            "description": "Workflow runs that took it as an input.",
            "title": "Jobs",
            "type": "integer"
          },
          "records": {
            "description": "Live records that use this file, across all collections.",
            "title": "Records",
            "type": "integer"
          },
          "sha256": {
            "title": "Sha256",
            "type": "string"
          },
          "size": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Size in bytes, if known.",
            "title": "Size"
          },
          "uses": {
            "description": "The live records that use it, named, with the records above each (at most 200; `records` is the full count).",
            "items": {
              "$ref": "#/components/schemas/RecordUseResponse"
            },
            "title": "Uses",
            "type": "array"
          }
        },
        "required": [
          "sha256",
          "size",
          "copies",
          "records",
          "jobs",
          "collections"
        ],
        "title": "FileInfoResponse",
        "type": "object"
      },
      "FileListRequest": {
        "properties": {
          "base": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix) that paths start below; defaults to 'within'.",
            "title": "Base"
          },
          "below": {
            "default": false,
            "description": "Also take the files of every record beneath each selected one (the selected encounters, and everything inside them). Without it, only the selected records' own files.",
            "title": "Below",
            "type": "boolean"
          },
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only this collection.",
            "title": "Collection"
          },
          "export": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "An export saved with a schema, as 'schema/name': its kind of record, file fields, filter, layout and tables become the selection, run in 'collection' and/or within the record 'within'. Sending 'layout', 'tables' or 'files' overrides what it has.",
            "title": "Export"
          },
          "fields": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these file fields; omit for every one.",
            "title": "Fields"
          },
          "files": {
            "default": true,
            "description": "False takes the tables alone, with no files (needs 'tables').",
            "title": "Files",
            "type": "boolean"
          },
          "filter": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A filter tree, as for listing records.",
            "title": "Filter"
          },
          "kinds": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of these kinds (schema names), when 'schema_name' is not given: how a preview of an export that takes any kind beneath a schema stays within that schema's own tree.",
            "title": "Kinds"
          },
          "layout": {
            "default": "tree",
            "description": "'tree' puts each file in a folder per record above it; 'grouped' gathers the files of the records that hold them into one folder named for their kind (Encounter/Recording/Selections/...); 'flat' puts every file in one folder. Names that clash in a shared folder are told apart by the record that owns each. A saved view carries its own (files_layout); sending this with 'view' overrides it.",
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Layout",
            "type": "string"
          },
          "limit": {
            "default": 100,
            "maximum": 1000.0,
            "minimum": 1.0,
            "title": "Limit",
            "type": "integer"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files whose name, or whose record's name, contains this.",
            "title": "Name"
          },
          "offset": {
            "default": 0,
            "minimum": 0.0,
            "title": "Offset",
            "type": "integer"
          },
          "order": {
            "default": "path",
            "description": "path, name, size, record or place; a leading '-' reverses it.",
            "title": "Order",
            "type": "string"
          },
          "place": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files in this place: a drive's name, `server` (only on the server), `missing`, or the groups `here` (on a drive that can be read now) and `unreachable` (on one that can't).",
            "title": "Place"
          },
          "record_ids": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exactly these records (the rows ticked in a list); the other selectors are then ignored.",
            "title": "Record Ids"
          },
          "schema_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of this schema.",
            "title": "Schema Name"
          },
          "search": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Full-text search.",
            "title": "Search"
          },
          "shas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "maxItems": 100000,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these files (by content hash), e.g. the ticked rows: each with every use of it in the selection. Records outside the selection that use the same file are not picked.",
            "title": "Shas"
          },
          "sort": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The order of the records, and so of the rows of a table: [{'field': name, 'direction': 'asc'|'desc'}, ...].",
            "title": "Sort"
          },
          "tables": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TableRequest"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Also make these tables. Each file column in one says where that file is in the export. Sending it overrides the tables a saved 'export' has; an empty list removes them.",
            "title": "Tables"
          },
          "used_by": {
            "anyOf": [
              {
                "items": {
                  "type": "integer"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files used by exactly one of these numbers of live records (anywhere, not only in the selection).",
            "title": "Used By"
          },
          "view": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A saved view as 'schema/view': its filter, its file columns and its layout become the selection ('collection' and 'within' still narrow it).",
            "title": "View"
          },
          "where": {
            "description": "'field=value' terms.",
            "items": {
              "type": "string"
            },
            "title": "Where",
            "type": "array"
          },
          "with_within": {
            "default": false,
            "description": "With `within` and `schema_name`: also the files of the `within` record itself (a list of what a record contains, taking the record's own files too).",
            "title": "With Within",
            "type": "boolean"
          },
          "within": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix): its files and those of everything beneath it. Paths start below it. With 'schema_name', only that schema's records under it.",
            "title": "Within"
          }
        },
        "title": "FileListRequest",
        "type": "object"
      },
      "FilePickRequest": {
        "properties": {
          "base": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix) that paths start below; defaults to 'within'.",
            "title": "Base"
          },
          "below": {
            "default": false,
            "description": "Also take the files of every record beneath each selected one (the selected encounters, and everything inside them). Without it, only the selected records' own files.",
            "title": "Below",
            "type": "boolean"
          },
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only this collection.",
            "title": "Collection"
          },
          "export": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "An export saved with a schema, as 'schema/name': its kind of record, file fields, filter, layout and tables become the selection, run in 'collection' and/or within the record 'within'. Sending 'layout', 'tables' or 'files' overrides what it has.",
            "title": "Export"
          },
          "fields": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these file fields; omit for every one.",
            "title": "Fields"
          },
          "files": {
            "default": true,
            "description": "False takes the tables alone, with no files (needs 'tables').",
            "title": "Files",
            "type": "boolean"
          },
          "filter": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A filter tree, as for listing records.",
            "title": "Filter"
          },
          "kinds": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of these kinds (schema names), when 'schema_name' is not given: how a preview of an export that takes any kind beneath a schema stays within that schema's own tree.",
            "title": "Kinds"
          },
          "layout": {
            "default": "tree",
            "description": "'tree' puts each file in a folder per record above it; 'grouped' gathers the files of the records that hold them into one folder named for their kind (Encounter/Recording/Selections/...); 'flat' puts every file in one folder. Names that clash in a shared folder are told apart by the record that owns each. A saved view carries its own (files_layout); sending this with 'view' overrides it.",
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Layout",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files whose name, or whose record's name, contains this.",
            "title": "Name"
          },
          "place": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files in this place: a drive's name, `server` (only on the server), `missing`, or the groups `here` (on a drive that can be read now) and `unreachable` (on one that can't).",
            "title": "Place"
          },
          "record_ids": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exactly these records (the rows ticked in a list); the other selectors are then ignored.",
            "title": "Record Ids"
          },
          "schema_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of this schema.",
            "title": "Schema Name"
          },
          "search": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Full-text search.",
            "title": "Search"
          },
          "shas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "maxItems": 100000,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these files (by content hash), e.g. the ticked rows: each with every use of it in the selection. Records outside the selection that use the same file are not picked.",
            "title": "Shas"
          },
          "sort": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The order of the records, and so of the rows of a table: [{'field': name, 'direction': 'asc'|'desc'}, ...].",
            "title": "Sort"
          },
          "tables": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TableRequest"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Also make these tables. Each file column in one says where that file is in the export. Sending it overrides the tables a saved 'export' has; an empty list removes them.",
            "title": "Tables"
          },
          "used_by": {
            "anyOf": [
              {
                "items": {
                  "type": "integer"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files used by exactly one of these numbers of live records (anywhere, not only in the selection).",
            "title": "Used By"
          },
          "view": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A saved view as 'schema/view': its filter, its file columns and its layout become the selection ('collection' and 'within' still narrow it).",
            "title": "View"
          },
          "where": {
            "description": "'field=value' terms.",
            "items": {
              "type": "string"
            },
            "title": "Where",
            "type": "array"
          },
          "with_within": {
            "default": false,
            "description": "With `within` and `schema_name`: also the files of the `within` record itself (a list of what a record contains, taking the record's own files too).",
            "title": "With Within",
            "type": "boolean"
          },
          "within": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix): its files and those of everything beneath it. Paths start below it. With 'schema_name', only that schema's records under it.",
            "title": "Within"
          }
        },
        "title": "FilePickRequest",
        "type": "object"
      },
      "FilePlanRequest": {
        "properties": {
          "base": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix) that paths start below; defaults to 'within'.",
            "title": "Base"
          },
          "below": {
            "default": false,
            "description": "Also take the files of every record beneath each selected one (the selected encounters, and everything inside them). Without it, only the selected records' own files.",
            "title": "Below",
            "type": "boolean"
          },
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only this collection.",
            "title": "Collection"
          },
          "export": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "An export saved with a schema, as 'schema/name': its kind of record, file fields, filter, layout and tables become the selection, run in 'collection' and/or within the record 'within'. Sending 'layout', 'tables' or 'files' overrides what it has.",
            "title": "Export"
          },
          "fields": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these file fields; omit for every one.",
            "title": "Fields"
          },
          "files": {
            "default": true,
            "description": "False takes the tables alone, with no files (needs 'tables').",
            "title": "Files",
            "type": "boolean"
          },
          "filter": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A filter tree, as for listing records.",
            "title": "Filter"
          },
          "include_items": {
            "default": true,
            "description": "Send the files too, not just the totals.",
            "title": "Include Items",
            "type": "boolean"
          },
          "kinds": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of these kinds (schema names), when 'schema_name' is not given: how a preview of an export that takes any kind beneath a schema stays within that schema's own tree.",
            "title": "Kinds"
          },
          "layout": {
            "default": "tree",
            "description": "'tree' puts each file in a folder per record above it; 'grouped' gathers the files of the records that hold them into one folder named for their kind (Encounter/Recording/Selections/...); 'flat' puts every file in one folder. Names that clash in a shared folder are told apart by the record that owns each. A saved view carries its own (files_layout); sending this with 'view' overrides it.",
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Layout",
            "type": "string"
          },
          "limit": {
            "anyOf": [
              {
                "maximum": 5000.0,
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "How many files to send.",
            "title": "Limit"
          },
          "offset": {
            "default": 0,
            "description": "First file to send.",
            "minimum": 0.0,
            "title": "Offset",
            "type": "integer"
          },
          "record_ids": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exactly these records (the rows ticked in a list); the other selectors are then ignored.",
            "title": "Record Ids"
          },
          "schema_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of this schema.",
            "title": "Schema Name"
          },
          "search": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Full-text search.",
            "title": "Search"
          },
          "sort": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The order of the records, and so of the rows of a table: [{'field': name, 'direction': 'asc'|'desc'}, ...].",
            "title": "Sort"
          },
          "tables": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TableRequest"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Also make these tables. Each file column in one says where that file is in the export. Sending it overrides the tables a saved 'export' has; an empty list removes them.",
            "title": "Tables"
          },
          "view": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A saved view as 'schema/view': its filter, its file columns and its layout become the selection ('collection' and 'within' still narrow it).",
            "title": "View"
          },
          "where": {
            "description": "'field=value' terms.",
            "items": {
              "type": "string"
            },
            "title": "Where",
            "type": "array"
          },
          "with_within": {
            "default": false,
            "description": "With `within` and `schema_name`: also the files of the `within` record itself (a list of what a record contains, taking the record's own files too).",
            "title": "With Within",
            "type": "boolean"
          },
          "within": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix): its files and those of everything beneath it. Paths start below it. With 'schema_name', only that schema's records under it.",
            "title": "Within"
          }
        },
        "title": "FilePlanRequest",
        "type": "object"
      },
      "FileRefResponse": {
        "properties": {
          "filename": {
            "title": "Filename",
            "type": "string"
          },
          "sha256": {
            "title": "Sha256",
            "type": "string"
          },
          "size": {
            "title": "Size",
            "type": "integer"
          },
          "volume": {
            "default": "default",
            "title": "Volume",
            "type": "string"
          }
        },
        "required": [
          "sha256",
          "filename",
          "size"
        ],
        "title": "FileRefResponse",
        "type": "object"
      },
      "FileZipRequest": {
        "properties": {
          "allow_partial": {
            "default": false,
            "description": "Zip what can be reached; the archive then holds MISSING.txt.",
            "title": "Allow Partial",
            "type": "boolean"
          },
          "base": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix) that paths start below; defaults to 'within'.",
            "title": "Base"
          },
          "below": {
            "default": false,
            "description": "Also take the files of every record beneath each selected one (the selected encounters, and everything inside them). Without it, only the selected records' own files.",
            "title": "Below",
            "type": "boolean"
          },
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only this collection.",
            "title": "Collection"
          },
          "export": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "An export saved with a schema, as 'schema/name': its kind of record, file fields, filter, layout and tables become the selection, run in 'collection' and/or within the record 'within'. Sending 'layout', 'tables' or 'files' overrides what it has.",
            "title": "Export"
          },
          "fields": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these file fields; omit for every one.",
            "title": "Fields"
          },
          "files": {
            "default": true,
            "description": "False takes the tables alone, with no files (needs 'tables').",
            "title": "Files",
            "type": "boolean"
          },
          "filter": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A filter tree, as for listing records.",
            "title": "Filter"
          },
          "kinds": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of these kinds (schema names), when 'schema_name' is not given: how a preview of an export that takes any kind beneath a schema stays within that schema's own tree.",
            "title": "Kinds"
          },
          "layout": {
            "default": "tree",
            "description": "'tree' puts each file in a folder per record above it; 'grouped' gathers the files of the records that hold them into one folder named for their kind (Encounter/Recording/Selections/...); 'flat' puts every file in one folder. Names that clash in a shared folder are told apart by the record that owns each. A saved view carries its own (files_layout); sending this with 'view' overrides it.",
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Layout",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Names the download: <name>.zip. Defaults to 'files'.",
            "title": "Name"
          },
          "record_ids": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exactly these records (the rows ticked in a list); the other selectors are then ignored.",
            "title": "Record Ids"
          },
          "schema_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only records of this schema.",
            "title": "Schema Name"
          },
          "search": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Full-text search.",
            "title": "Search"
          },
          "sort": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The order of the records, and so of the rows of a table: [{'field': name, 'direction': 'asc'|'desc'}, ...].",
            "title": "Sort"
          },
          "tables": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TableRequest"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Also make these tables. Each file column in one says where that file is in the export. Sending it overrides the tables a saved 'export' has; an empty list removes them.",
            "title": "Tables"
          },
          "view": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A saved view as 'schema/view': its filter, its file columns and its layout become the selection ('collection' and 'within' still narrow it).",
            "title": "View"
          },
          "where": {
            "description": "'field=value' terms.",
            "items": {
              "type": "string"
            },
            "title": "Where",
            "type": "array"
          },
          "with_within": {
            "default": false,
            "description": "With `within` and `schema_name`: also the files of the `within` record itself (a list of what a record contains, taking the record's own files too).",
            "title": "With Within",
            "type": "boolean"
          },
          "within": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A record (id or prefix): its files and those of everything beneath it. Paths start below it. With 'schema_name', only that schema's records under it.",
            "title": "Within"
          }
        },
        "title": "FileZipRequest",
        "type": "object"
      },
      "ForgetPurgedRequest": {
        "properties": {
          "dry_run": {
            "default": true,
            "description": "Only count the entries that would be deleted.",
            "title": "Dry Run",
            "type": "boolean"
          }
        },
        "title": "ForgetPurgedRequest",
        "type": "object"
      },
      "ForgetPurgedResponse": {
        "properties": {
          "dry_run": {
            "title": "Dry Run",
            "type": "boolean"
          },
          "entries": {
            "description": "History entries about records that no longer exist.",
            "title": "Entries",
            "type": "integer"
          }
        },
        "required": [
          "dry_run",
          "entries"
        ],
        "title": "ForgetPurgedResponse",
        "type": "object"
      },
      "FreeUpResponse": {
        "properties": {
          "bytes": {
            "description": "The space that frees.",
            "title": "Bytes",
            "type": "integer"
          },
          "done": {
            "description": "False when only counted.",
            "title": "Done",
            "type": "boolean"
          },
          "files": {
            "description": "Copies removed (or that would be, counting).",
            "title": "Files",
            "type": "integer"
          },
          "kept_shared": {
            "description": "Kept: also used by a collection kept on this computer.",
            "title": "Kept Shared",
            "type": "integer"
          },
          "not_on_server": {
            "description": "Kept: the server hasn't got them yet (never sent).",
            "title": "Not On Server",
            "type": "integer"
          }
        },
        "required": [
          "files",
          "bytes",
          "kept_shared",
          "not_on_server",
          "done"
        ],
        "title": "FreeUpResponse",
        "type": "object"
      },
      "GCReportResponse": {
        "properties": {
          "deleted": {
            "items": {
              "$ref": "#/components/schemas/StoredObjectResponse"
            },
            "title": "Deleted",
            "type": "array"
          },
          "deleted_bytes": {
            "title": "Deleted Bytes",
            "type": "integer"
          },
          "deleted_count": {
            "description": "Objects deleted (or, if dry_run, collectible).",
            "title": "Deleted Count",
            "type": "integer"
          },
          "dry_run": {
            "description": "True if no objects were actually deleted.",
            "title": "Dry Run",
            "type": "boolean"
          },
          "grace_days": {
            "title": "Grace Days",
            "type": "integer"
          },
          "protected_by_grace": {
            "description": "Unreferenced objects skipped for being younger than the grace period.",
            "title": "Protected By Grace",
            "type": "integer"
          },
          "referenced": {
            "description": "Distinct content hashes reachable from a live record or workflow job.",
            "title": "Referenced",
            "type": "integer"
          },
          "scanned": {
            "description": "Total objects found in the store.",
            "title": "Scanned",
            "type": "integer"
          },
          "stale_scratch_removed": {
            "description": "Abandoned upload scratch files (from an interrupted streamed upload) removed, or if dry_run, collectible.",
            "title": "Stale Scratch Removed",
            "type": "integer"
          },
          "volume": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The volume this pass was limited to, or null for every volume.",
            "title": "Volume"
          }
        },
        "required": [
          "dry_run",
          "grace_days",
          "scanned",
          "referenced",
          "protected_by_grace",
          "deleted_count",
          "deleted_bytes",
          "deleted",
          "stale_scratch_removed"
        ],
        "title": "GCReportResponse",
        "type": "object"
      },
      "GCRequest": {
        "properties": {
          "apply": {
            "default": false,
            "description": "Actually delete collectible objects. False (default) only reports what would be deleted.",
            "title": "Apply",
            "type": "boolean"
          },
          "grace_days": {
            "default": 14,
            "description": "Skip unreferenced objects written more recently than this many days.",
            "minimum": 0.0,
            "title": "Grace Days",
            "type": "integer"
          },
          "rebuild_refs": {
            "default": false,
            "description": "Recompute the file-reference table from every record and job before collecting. Normally unnecessary; use if the table may have drifted.",
            "title": "Rebuild Refs",
            "type": "boolean"
          },
          "volume": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only collect objects stored on this volume. Omit to clean up every volume.",
            "title": "Volume"
          }
        },
        "title": "GCRequest",
        "type": "object"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "title": "Detail",
            "type": "array"
          }
        },
        "title": "HTTPValidationError",
        "type": "object"
      },
      "HistoryStorageResponse": {
        "properties": {
          "converting": {
            "description": "The conversion is running now.",
            "title": "Converting",
            "type": "boolean"
          },
          "done": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Entries looked at since the conversion began.",
            "title": "Done"
          },
          "free_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Room inside the file no longer used: what reclaiming gives back. Reclaiming needs about `size_bytes` of free disk while it runs.",
            "title": "Free Bytes"
          },
          "size_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The database file's size (SQLite; null where the database manages its own space).",
            "title": "Size Bytes"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "What was left when the conversion began.",
            "title": "Total"
          },
          "whole_entries": {
            "description": "Edits still stored as two whole copies (written before history stored only what changed); converted in the background.",
            "title": "Whole Entries",
            "type": "integer"
          }
        },
        "required": [
          "whole_entries",
          "converting"
        ],
        "title": "HistoryStorageResponse",
        "type": "object"
      },
      "IdentityResponse": {
        "properties": {
          "chosen": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The name chosen for this project, or null when none is.",
            "title": "Chosen"
          },
          "default": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What is used when none is chosen: the operating-system user.",
            "title": "Default"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What changes made here are recorded as.",
            "title": "Name"
          }
        },
        "required": [
          "name",
          "chosen",
          "default"
        ],
        "title": "IdentityResponse",
        "type": "object"
      },
      "InstallPlanResponse": {
        "properties": {
          "blocked": {
            "description": "Why it can't be installed as asked.",
            "items": {
              "type": "string"
            },
            "title": "Blocked",
            "type": "array"
          },
          "breaks": {
            "description": "What the new plugin versions would break among the workflows here.",
            "items": {
              "type": "string"
            },
            "title": "Breaks",
            "type": "array"
          },
          "runs_code": {
            "description": "It writes a plugin, which is code this computer will run.",
            "title": "Runs Code",
            "type": "boolean"
          },
          "steps": {
            "items": {
              "$ref": "#/components/schemas/InstallStepResponse"
            },
            "title": "Steps",
            "type": "array"
          },
          "warnings": {
            "description": "What to know first (what starts a workflow by itself).",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "steps",
          "blocked",
          "warnings",
          "runs_code"
        ],
        "title": "InstallPlanResponse",
        "type": "object"
      },
      "InstallStepResponse": {
        "properties": {
          "here": {
            "description": "absent, same, older or different, before installing.",
            "title": "Here",
            "type": "string"
          },
          "item": {
            "$ref": "#/components/schemas/LibraryItemResponse"
          },
          "local_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The library version here now, if any.",
            "title": "Local Version"
          },
          "path": {
            "description": "Where it is written, in the project.",
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "item",
          "path",
          "here"
        ],
        "title": "InstallStepResponse",
        "type": "object"
      },
      "InviteRequest": {
        "properties": {
          "hours": {
            "default": 24,
            "description": "How long the invite works.",
            "title": "Hours",
            "type": "integer"
          },
          "name": {
            "description": "What to call the device.",
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "InviteRequest",
        "type": "object"
      },
      "InviteResponse": {
        "properties": {
          "created_at": {
            "title": "Created At",
            "type": "string"
          },
          "expires_at": {
            "title": "Expires At",
            "type": "string"
          },
          "name": {
            "description": "The device it is for.",
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "created_at",
          "expires_at"
        ],
        "title": "InviteResponse",
        "type": "object"
      },
      "InvitedResponse": {
        "properties": {
          "devices": {
            "description": "The devices that joined.",
            "items": {
              "$ref": "#/components/schemas/DeviceResponse"
            },
            "title": "Devices",
            "type": "array"
          },
          "fingerprint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "This authority's key's short code; null until it first invites.",
            "title": "Fingerprint"
          },
          "invite": {
            "description": "The invite, for the device to connect with. Shown once: only its hash is kept. It works once.",
            "title": "Invite",
            "type": "string"
          },
          "invites": {
            "description": "Invites not used yet and not expired.",
            "items": {
              "$ref": "#/components/schemas/InviteResponse"
            },
            "title": "Invites",
            "type": "array"
          },
          "library": {
            "default": "workflows",
            "description": "What devices allowed to publish may share through this server's library: off, workflows, or all (plugins too, which are code).",
            "title": "Library",
            "type": "string"
          },
          "serving": {
            "description": "This project accepts devices.",
            "title": "Serving",
            "type": "boolean"
          }
        },
        "required": [
          "serving",
          "fingerprint",
          "devices",
          "invites",
          "invite"
        ],
        "title": "InvitedResponse",
        "type": "object"
      },
      "JobDurationStatsResponse": {
        "properties": {
          "avg_seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Avg Seconds"
          },
          "bins": {
            "description": "Duration distribution, bucketed into fixed-width ranges.",
            "items": {
              "$ref": "#/components/schemas/DurationHistogramBinResponse"
            },
            "title": "Bins",
            "type": "array"
          },
          "count": {
            "description": "Number of step executions the stats are over.",
            "title": "Count",
            "type": "integer"
          },
          "max_seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Seconds"
          },
          "min_seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Min Seconds"
          },
          "p50_seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "P50 Seconds"
          },
          "p90_seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "P90 Seconds"
          },
          "p99_seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "P99 Seconds"
          },
          "percentile_markers": {
            "description": "Which bucket each of p50/p90/p99 falls in, for a chart to draw as reference lines over `bins`.",
            "items": {
              "$ref": "#/components/schemas/DurationPercentileMarkerResponse"
            },
            "title": "Percentile Markers",
            "type": "array"
          }
        },
        "required": [
          "count",
          "avg_seconds",
          "min_seconds",
          "max_seconds",
          "p50_seconds",
          "p90_seconds",
          "p99_seconds",
          "bins",
          "percentile_markers"
        ],
        "title": "JobDurationStatsResponse",
        "type": "object"
      },
      "JobStatusCountsResponse": {
        "properties": {
          "bucket": {
            "title": "Bucket",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/JobStatusPointResponse"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "bucket",
          "items"
        ],
        "title": "JobStatusCountsResponse",
        "type": "object"
      },
      "JobStatusPointResponse": {
        "properties": {
          "bucket": {
            "title": "Bucket",
            "type": "string"
          },
          "count": {
            "title": "Count",
            "type": "integer"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "bucket",
          "status",
          "count"
        ],
        "title": "JobStatusPointResponse",
        "type": "object"
      },
      "LibraryInstallRequest": {
        "properties": {
          "force": {
            "default": false,
            "description": "Install even though it would break workflows here.",
            "title": "Force",
            "type": "boolean"
          },
          "replace": {
            "default": false,
            "description": "Replace files here that were changed here.",
            "title": "Replace",
            "type": "boolean"
          },
          "version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Omit for the newest.",
            "title": "Version"
          },
          "with_plugins": {
            "default": true,
            "description": "A workflow: install the plugin versions it is pinned to too.",
            "title": "With Plugins",
            "type": "boolean"
          }
        },
        "title": "LibraryInstallRequest",
        "type": "object"
      },
      "LibraryItemBody": {
        "properties": {
          "content": {
            "description": "The file's text.",
            "maxLength": 262144,
            "title": "Content",
            "type": "string"
          },
          "contract": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A plugin: its contract (inputs, outputs, config schema) as the publisher's computer described it.",
            "title": "Contract"
          },
          "kind": {
            "description": "workflow or plugin.",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "description": "The file's name without its extension.",
            "title": "Name",
            "type": "string"
          },
          "provides": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A plugin: the plugin id it registers as.",
            "title": "Provides"
          },
          "sha256": {
            "description": "The hash of `content`, as UTF-8.",
            "title": "Sha256",
            "type": "string"
          },
          "size": {
            "default": 0,
            "description": "Its size in bytes.",
            "title": "Size",
            "type": "integer"
          }
        },
        "required": [
          "kind",
          "name",
          "sha256",
          "content"
        ],
        "title": "LibraryItemBody",
        "type": "object"
      },
      "LibraryItemResponse": {
        "properties": {
          "content": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its text, when asked for one.",
            "title": "Content"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "filename": {
            "title": "Filename",
            "type": "string"
          },
          "here": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "On this computer, against this version: absent, same, older (an earlier version from the library) or different (changed here).",
            "title": "Here"
          },
          "history": {
            "description": "Every version, newest first.",
            "items": {
              "$ref": "#/components/schemas/LibraryVersionResponse"
            },
            "title": "History",
            "type": "array"
          },
          "kind": {
            "description": "workflow or plugin.",
            "title": "Kind",
            "type": "string"
          },
          "local_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The library version this computer has, if any.",
            "title": "Local Version"
          },
          "missing": {
            "description": "Plugins it needs that are neither here nor in the library.",
            "items": {
              "type": "string"
            },
            "title": "Missing",
            "type": "array"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "needs": {
            "description": "A workflow: the plugins its steps use.",
            "items": {
              "type": "string"
            },
            "title": "Needs",
            "type": "array"
          },
          "pins": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "A workflow: the version of each plugin it was published with.",
            "title": "Pins",
            "type": "object"
          },
          "provides": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A plugin: the plugin id it registers as.",
            "title": "Provides"
          },
          "published_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Published At"
          },
          "published_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Published By"
          },
          "sha256": {
            "title": "Sha256",
            "type": "string"
          },
          "size": {
            "title": "Size",
            "type": "integer"
          },
          "title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A workflow's own name.",
            "title": "Title"
          },
          "triggers": {
            "description": "A workflow: what starts it by itself.",
            "items": {
              "type": "string"
            },
            "title": "Triggers",
            "type": "array"
          },
          "version": {
            "description": "This version's number (the newest in a list).",
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "kind",
          "name",
          "filename",
          "sha256",
          "size",
          "version"
        ],
        "title": "LibraryItemResponse",
        "type": "object"
      },
      "LibraryListResponse": {
        "properties": {
          "items": {
            "description": "The newest version of each item, without its text: kind, name, sha256, size, version, title, description, provides, needs, triggers, pins, contract, published_by, published_at, and its history (every version).",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "LibraryListResponse",
        "type": "object"
      },
      "LibraryVersionResponse": {
        "properties": {
          "pins": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "A workflow: the plugin versions it was published with.",
            "title": "Pins",
            "type": "object"
          },
          "published_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Published At"
          },
          "published_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Published By"
          },
          "sha256": {
            "title": "Sha256",
            "type": "string"
          },
          "version": {
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "version",
          "sha256"
        ],
        "title": "LibraryVersionResponse",
        "type": "object"
      },
      "LicenseResponse": {
        "properties": {
          "text": {
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "title": "LicenseResponse",
        "type": "object"
      },
      "MapSettingsResponse": {
        "properties": {
          "attribution": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credit shown on the map for the tile provider, as plain text.",
            "title": "Attribution"
          },
          "tile_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "XYZ tile URL for the location editor's street-level map, with {z}, {x} and {y} placeholders. Null means the editor uses only its bundled coastlines.",
            "title": "Tile Url"
          }
        },
        "required": [
          "tile_url",
          "attribution"
        ],
        "title": "MapSettingsResponse",
        "type": "object"
      },
      "MigrationStatusResponse": {
        "properties": {
          "current_revision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Revision"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "head_revision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Head Revision"
          },
          "up_to_date": {
            "title": "Up To Date",
            "type": "boolean"
          }
        },
        "required": [
          "current_revision",
          "head_revision",
          "up_to_date"
        ],
        "title": "MigrationStatusResponse",
        "type": "object"
      },
      "ModelUsageResponse": {
        "properties": {
          "input_tokens": {
            "title": "Input Tokens",
            "type": "integer"
          },
          "model": {
            "title": "Model",
            "type": "string"
          },
          "output_tokens": {
            "title": "Output Tokens",
            "type": "integer"
          },
          "provider": {
            "title": "Provider",
            "type": "string"
          },
          "requests": {
            "title": "Requests",
            "type": "integer"
          },
          "total_tokens": {
            "title": "Total Tokens",
            "type": "integer"
          }
        },
        "required": [
          "provider",
          "model",
          "requests",
          "input_tokens",
          "output_tokens",
          "total_tokens"
        ],
        "title": "ModelUsageResponse",
        "type": "object"
      },
      "MoveJobResponse": {
        "properties": {
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why it failed or was cancelled.",
            "title": "Error"
          },
          "id": {
            "description": "Job id to poll.",
            "title": "Id",
            "type": "string"
          },
          "progress": {
            "$ref": "#/components/schemas/MoveProgressResponse",
            "description": "Latest progress."
          },
          "record": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MoveRecordResponse"
              },
              {
                "type": "null"
              }
            ],
            "description": "The history entry, once the move has ended."
          },
          "status": {
            "description": "State of the move.",
            "enum": [
              "running",
              "done",
              "failed",
              "cancelled"
            ],
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "id",
          "status",
          "progress"
        ],
        "title": "MoveJobResponse",
        "type": "object"
      },
      "MovePreflightResponse": {
        "properties": {
          "can_proceed": {
            "description": "False when `problems` is not empty.",
            "title": "Can Proceed",
            "type": "boolean"
          },
          "estimate_seconds": {
            "description": "Rough time the copy will take.",
            "title": "Estimate Seconds",
            "type": "integer"
          },
          "problems": {
            "description": "Reasons the move can't go ahead.",
            "items": {
              "type": "string"
            },
            "title": "Problems",
            "type": "array"
          },
          "source": {
            "$ref": "#/components/schemas/DatabaseSummaryResponse",
            "description": "The database now in use."
          },
          "target": {
            "$ref": "#/components/schemas/DatabaseSummaryResponse",
            "description": "The destination."
          },
          "target_label": {
            "description": "Kind of destination, for display.",
            "title": "Target Label",
            "type": "string"
          },
          "warnings": {
            "description": "Things worth knowing that don't block it.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "source",
          "target",
          "target_label",
          "can_proceed",
          "problems",
          "warnings",
          "estimate_seconds"
        ],
        "title": "MovePreflightResponse",
        "type": "object"
      },
      "MoveProgressResponse": {
        "properties": {
          "message": {
            "description": "What it is doing, for display.",
            "title": "Message",
            "type": "string"
          },
          "phase": {
            "description": "'copy', 'verify' or 'finalize'.",
            "title": "Phase",
            "type": "string"
          },
          "rows_done": {
            "description": "Rows copied so far.",
            "title": "Rows Done",
            "type": "integer"
          },
          "rows_total": {
            "description": "Rows to copy in all.",
            "title": "Rows Total",
            "type": "integer"
          },
          "table": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Table being copied.",
            "title": "Table"
          },
          "tables_done": {
            "description": "Tables finished.",
            "title": "Tables Done",
            "type": "integer"
          },
          "tables_total": {
            "description": "Tables to copy.",
            "title": "Tables Total",
            "type": "integer"
          }
        },
        "required": [
          "phase",
          "rows_done",
          "rows_total",
          "tables_done",
          "tables_total",
          "message"
        ],
        "title": "MoveProgressResponse",
        "type": "object"
      },
      "MoveRecordResponse": {
        "properties": {
          "counts": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Rows copied per table.",
            "title": "Counts",
            "type": "object"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why it didn't finish.",
            "title": "Error"
          },
          "finished_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it ended.",
            "title": "Finished At"
          },
          "id": {
            "description": "Identifier of the move.",
            "title": "Id",
            "type": "string"
          },
          "problems": {
            "description": "What didn't match, if verification failed.",
            "items": {
              "type": "string"
            },
            "title": "Problems",
            "type": "array"
          },
          "reverted_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it was undone, if it was.",
            "title": "Reverted At"
          },
          "seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "How long the copy took.",
            "title": "Seconds"
          },
          "source_label": {
            "description": "Kind of database moved from.",
            "title": "Source Label",
            "type": "string"
          },
          "source_location": {
            "description": "Where it was, password hidden.",
            "title": "Source Location",
            "type": "string"
          },
          "started_at": {
            "description": "When it started (ISO 8601).",
            "title": "Started At",
            "type": "string"
          },
          "status": {
            "description": "Outcome. Only 'done' means the project now uses the new database.",
            "enum": [
              "running",
              "done",
              "failed",
              "cancelled"
            ],
            "title": "Status",
            "type": "string"
          },
          "target_label": {
            "description": "Kind of database moved to.",
            "title": "Target Label",
            "type": "string"
          },
          "target_location": {
            "description": "Where it is, password hidden.",
            "title": "Target Location",
            "type": "string"
          }
        },
        "required": [
          "id",
          "started_at",
          "status",
          "source_label",
          "source_location",
          "target_label",
          "target_location",
          "counts",
          "problems"
        ],
        "title": "MoveRecordResponse",
        "type": "object"
      },
      "MoveTargetRequest": {
        "properties": {
          "database": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Database name, for kind 'postgres'.",
            "title": "Database"
          },
          "host": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Server host, for kind 'postgres'.",
            "title": "Host"
          },
          "kind": {
            "description": "Where to move to: 'sqlite' (a new file in the project), 'docker' (this project's Civex-managed PostgreSQL container) or 'postgres' (a PostgreSQL server you run).",
            "enum": [
              "sqlite",
              "docker",
              "postgres"
            ],
            "title": "Kind",
            "type": "string"
          },
          "password": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Password, for kind 'postgres'.",
            "title": "Password"
          },
          "path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "File to create, for kind 'sqlite'. Defaults to a new file in _civex/.",
            "title": "Path"
          },
          "port": {
            "default": 5432,
            "description": "Server port, for kind 'postgres'.",
            "title": "Port",
            "type": "integer"
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Full connection URL, for kind 'postgres' (instead of the fields below).",
            "title": "Url"
          },
          "user": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "User name, for kind 'postgres'.",
            "title": "User"
          }
        },
        "required": [
          "kind"
        ],
        "title": "MoveTargetRequest",
        "type": "object"
      },
      "NameIssueResponse": {
        "properties": {
          "kind": {
            "description": "'schema' or 'field'.",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "schema_name": {
            "title": "Schema Name",
            "type": "string"
          },
          "suggestion": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Slugified alternative; null if undecidable.",
            "title": "Suggestion"
          }
        },
        "required": [
          "kind",
          "schema_name",
          "name"
        ],
        "title": "NameIssueResponse",
        "type": "object"
      },
      "OpenBatchRequest": {
        "properties": {
          "kind": {
            "const": "import",
            "default": "import",
            "description": "What the batch is. Only an import is opened by a client; the server opens its own for deletes, restores and workflow runs.",
            "title": "Kind",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "E.g. the file imported.",
            "title": "Label"
          }
        },
        "title": "OpenBatchRequest",
        "type": "object"
      },
      "OrphanResponse": {
        "properties": {
          "above": {
            "description": "The deleted records directly above it, topmost first.",
            "items": {
              "$ref": "#/components/schemas/RecordRef"
            },
            "title": "Above",
            "type": "array"
          },
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The collection it is in.",
            "title": "Collection"
          },
          "record": {
            "$ref": "#/components/schemas/RecordRef"
          }
        },
        "required": [
          "record",
          "collection",
          "above"
        ],
        "title": "OrphanResponse",
        "type": "object"
      },
      "OrphansResponse": {
        "properties": {
          "items": {
            "description": "Up to `limit` of them.",
            "items": {
              "$ref": "#/components/schemas/OrphanResponse"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "description": "How many live records sit under a deleted one.",
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "total",
          "items"
        ],
        "title": "OrphansResponse",
        "type": "object"
      },
      "PaginatedAuditEventsResponse": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/AuditEventResponse"
            },
            "title": "Items",
            "type": "array"
          },
          "limit": {
            "title": "Limit",
            "type": "integer"
          },
          "offset": {
            "title": "Offset",
            "type": "integer"
          },
          "total": {
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total",
          "offset",
          "limit"
        ],
        "title": "PaginatedAuditEventsResponse",
        "type": "object"
      },
      "PaginatedAuditLogResponse": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/AuditLogResponse"
            },
            "title": "Items",
            "type": "array"
          },
          "limit": {
            "title": "Limit",
            "type": "integer"
          },
          "offset": {
            "title": "Offset",
            "type": "integer"
          },
          "total": {
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total",
          "offset",
          "limit"
        ],
        "title": "PaginatedAuditLogResponse",
        "type": "object"
      },
      "PaginatedRecordResponse": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/RecordResponse"
            },
            "title": "Items",
            "type": "array"
          },
          "limit": {
            "title": "Limit",
            "type": "integer"
          },
          "offset": {
            "title": "Offset",
            "type": "integer"
          },
          "total": {
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total",
          "offset",
          "limit"
        ],
        "title": "PaginatedRecordResponse",
        "type": "object"
      },
      "PathInspectionResponse": {
        "properties": {
          "existing_volume": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The configured volume already at this path, if any.",
            "title": "Existing Volume"
          },
          "exists": {
            "title": "Exists",
            "type": "boolean"
          },
          "free_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Free Bytes"
          },
          "has_civex_data": {
            "title": "Has Civex Data",
            "type": "boolean"
          },
          "inside_project": {
            "title": "Inside Project",
            "type": "boolean"
          },
          "is_dir": {
            "title": "Is Dir",
            "type": "boolean"
          },
          "is_network": {
            "description": "The folder is on a network filesystem.",
            "title": "Is Network",
            "type": "boolean"
          },
          "marker_volume": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The configured volume whose drive this is, if any.",
            "title": "Marker Volume"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "problems": {
            "description": "Reasons it can't be added as a volume.",
            "items": {
              "type": "string"
            },
            "title": "Problems",
            "type": "array"
          },
          "same_disk_as_project": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Same Disk As Project"
          },
          "total_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Bytes"
          },
          "warnings": {
            "description": "Things to know; they don't block adding it.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          },
          "will_create": {
            "description": "The folder doesn't exist and would be created.",
            "title": "Will Create",
            "type": "boolean"
          },
          "writable": {
            "title": "Writable",
            "type": "boolean"
          }
        },
        "required": [
          "path",
          "exists",
          "is_dir",
          "writable",
          "will_create",
          "inside_project",
          "same_disk_as_project",
          "free_bytes",
          "total_bytes",
          "existing_volume",
          "marker_volume",
          "has_civex_data",
          "is_network",
          "problems",
          "warnings"
        ],
        "title": "PathInspectionResponse",
        "type": "object"
      },
      "PlacementResponse": {
        "properties": {
          "collection_id": {
            "description": "Id of the collection this placement is for.",
            "title": "Collection Id",
            "type": "string"
          },
          "collection_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The collection's name, or null if it no longer exists.",
            "title": "Collection Name"
          },
          "on_unavailable": {
            "description": "spill: use the general write queue when the home volume can't take a file. fail: refuse the upload instead.",
            "title": "On Unavailable",
            "type": "string"
          },
          "volume": {
            "description": "The collection's home volume.",
            "title": "Volume",
            "type": "string"
          }
        },
        "required": [
          "collection_id",
          "collection_name",
          "volume",
          "on_unavailable"
        ],
        "title": "PlacementResponse",
        "type": "object"
      },
      "PluginFailureCountsResponse": {
        "properties": {
          "bucket": {
            "title": "Bucket",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/PluginFailurePointResponse"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "bucket",
          "items"
        ],
        "title": "PluginFailureCountsResponse",
        "type": "object"
      },
      "PluginFailurePointResponse": {
        "properties": {
          "bucket": {
            "title": "Bucket",
            "type": "string"
          },
          "count": {
            "title": "Count",
            "type": "integer"
          },
          "plugin": {
            "title": "Plugin",
            "type": "string"
          }
        },
        "required": [
          "bucket",
          "plugin",
          "count"
        ],
        "title": "PluginFailurePointResponse",
        "type": "object"
      },
      "PluginIOSpec": {
        "properties": {
          "description": {
            "title": "Description",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "required": {
            "title": "Required",
            "type": "boolean"
          },
          "type": {
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "name",
          "type",
          "required",
          "description"
        ],
        "title": "PluginIOSpec",
        "type": "object"
      },
      "PluginInfo": {
        "description": "Mirrors PluginService.list_registered() field-for-field (CIVEX-144) --\nthe frontend plugin panel and `civex plugin info` both read this same\nshape, so a field missing here silently vanishes from every UI even\nthough the service already returns it. `inputs`/`outputs` stay nullable:\nNone means the plugin declared no contract in that direction, `[]` means\nit declared it has none (see civex_plugin_sdk.PluginBase.inputs).",
        "properties": {
          "builtin": {
            "title": "Builtin",
            "type": "boolean"
          },
          "capabilities": {
            "items": {
              "type": "string"
            },
            "title": "Capabilities",
            "type": "array"
          },
          "category": {
            "title": "Category",
            "type": "string"
          },
          "config_schema": {
            "additionalProperties": true,
            "title": "Config Schema",
            "type": "object"
          },
          "description": {
            "title": "Description",
            "type": "string"
          },
          "filename": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Filename"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "inputs": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PluginIOSpec"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Inputs"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "outputs": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PluginIOSpec"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Outputs"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "builtin",
          "category",
          "capabilities",
          "inputs",
          "outputs",
          "config_schema"
        ],
        "title": "PluginInfo",
        "type": "object"
      },
      "PluginLoadError": {
        "properties": {
          "error": {
            "title": "Error",
            "type": "string"
          },
          "filename": {
            "title": "Filename",
            "type": "string"
          }
        },
        "required": [
          "filename",
          "error"
        ],
        "title": "PluginLoadError",
        "type": "object"
      },
      "PluginSaveRequest": {
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "code"
        ],
        "title": "PluginSaveRequest",
        "type": "object"
      },
      "PluginSource": {
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "filename": {
            "title": "Filename",
            "type": "string"
          }
        },
        "required": [
          "filename",
          "code"
        ],
        "title": "PluginSource",
        "type": "object"
      },
      "PolicyResponse": {
        "properties": {
          "content": {
            "title": "Content",
            "type": "string"
          },
          "stem": {
            "title": "Stem",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "stem",
          "title",
          "content"
        ],
        "title": "PolicyResponse",
        "type": "object"
      },
      "PreviewNameRequest": {
        "properties": {
          "kind": {
            "default": "record",
            "description": "'record' renders a record's name; 'file' renders a download name, where `{ext}` is available and a blank value makes the result null.",
            "enum": [
              "record",
              "file"
            ],
            "title": "Kind",
            "type": "string"
          },
          "template": {
            "description": "The template to try, e.g. '{site}-{taken_on:YYYY-MM}'.",
            "title": "Template",
            "type": "string"
          },
          "values": {
            "additionalProperties": true,
            "description": "Field values (keyed by field name) of the sample record to render against.",
            "title": "Values",
            "type": "object"
          }
        },
        "required": [
          "template"
        ],
        "title": "PreviewNameRequest",
        "type": "object"
      },
      "PreviewNameResponse": {
        "properties": {
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the template is not valid, if it is not.",
            "title": "Error"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The rendered text, or null when the template renders to nothing.",
            "title": "Name"
          }
        },
        "required": [
          "name"
        ],
        "title": "PreviewNameResponse",
        "type": "object"
      },
      "PreviewViewRequest": {
        "properties": {
          "columns": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Same shape as a view's 'columns' -- base schema field names and/or single-hop reference-field joins. Validated the same way, but not persisted.",
            "title": "Columns"
          },
          "filter_tree": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Same shape as a view's 'filter_tree'.",
            "title": "Filter Tree"
          },
          "limit": {
            "default": 50,
            "maximum": 1000.0,
            "minimum": 1.0,
            "title": "Limit",
            "type": "integer"
          },
          "offset": {
            "default": 0,
            "minimum": 0.0,
            "title": "Offset",
            "type": "integer"
          },
          "sort": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Same shape as a view's 'sort': the schema's own or an inherited field, each ascending or descending.",
            "title": "Sort"
          }
        },
        "title": "PreviewViewRequest",
        "type": "object"
      },
      "PreviewViewResponse": {
        "properties": {
          "rows": {
            "description": "One dict per matching record, keyed by column (joined columns use the 'ref_field.target_field' key).",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Rows",
            "type": "array"
          },
          "total": {
            "description": "Total matching records regardless of 'limit'/'offset'.",
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "rows",
          "total"
        ],
        "title": "PreviewViewResponse",
        "type": "object"
      },
      "RecordCountResponse": {
        "properties": {
          "count": {
            "title": "Count",
            "type": "integer"
          },
          "dataset": {
            "title": "Dataset",
            "type": "string"
          },
          "schema_name": {
            "title": "Schema Name",
            "type": "string"
          }
        },
        "required": [
          "dataset",
          "schema_name",
          "count"
        ],
        "title": "RecordCountResponse",
        "type": "object"
      },
      "RecordCountsResponse": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/RecordCountResponse"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "RecordCountsResponse",
        "type": "object"
      },
      "RecordGrowthPointResponse": {
        "properties": {
          "bucket": {
            "description": "ISO date the bucket starts on.",
            "title": "Bucket",
            "type": "string"
          },
          "count": {
            "title": "Count",
            "type": "integer"
          },
          "dataset": {
            "title": "Dataset",
            "type": "string"
          },
          "schema_name": {
            "title": "Schema Name",
            "type": "string"
          }
        },
        "required": [
          "bucket",
          "dataset",
          "schema_name",
          "count"
        ],
        "title": "RecordGrowthPointResponse",
        "type": "object"
      },
      "RecordGrowthResponse": {
        "properties": {
          "bucket": {
            "description": "Bucket size applied: day, week, or month.",
            "title": "Bucket",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/RecordGrowthPointResponse"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "bucket",
          "items"
        ],
        "title": "RecordGrowthResponse",
        "type": "object"
      },
      "RecordLabelResponse": {
        "properties": {
          "deleted": {
            "description": "True for a record in Recently Deleted (it can still be restored).",
            "title": "Deleted",
            "type": "boolean"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it was deleted; null for a live record.",
            "title": "Deleted At"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "natural_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The record's name as it is now: its schema's display template applied to its current values. Null when nothing in it can name it.",
            "title": "Natural Name"
          },
          "schema_name": {
            "description": "The record's schema.",
            "title": "Schema Name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "schema_name",
          "natural_name",
          "deleted"
        ],
        "title": "RecordLabelResponse",
        "type": "object"
      },
      "RecordLabelsRequest": {
        "properties": {
          "ids": {
            "description": "Record ids to look up. Anything that isn't a record is skipped.",
            "items": {
              "type": "string"
            },
            "maxItems": 200,
            "title": "Ids",
            "type": "array"
          }
        },
        "required": [
          "ids"
        ],
        "title": "RecordLabelsRequest",
        "type": "object"
      },
      "RecordRef": {
        "properties": {
          "id": {
            "title": "Id",
            "type": "string"
          },
          "natural_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Natural Name"
          },
          "schema_name": {
            "title": "Schema Name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "schema_name",
          "natural_name"
        ],
        "title": "RecordRef",
        "type": "object"
      },
      "RecordResponse": {
        "properties": {
          "ancestors": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/RecordRef"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only on a single-record fetch: the parent chain, root first, for breadcrumbs.",
            "title": "Ancestors"
          },
          "child_counts": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "integer"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only when requested ('child_counts=true'): how many live child records this record has, per child schema name.",
            "title": "Child Counts"
          },
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Name of the collection this record lives in.",
            "title": "Collection"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "data": {
            "additionalProperties": true,
            "title": "Data",
            "type": "object"
          },
          "dataset_id": {
            "title": "Dataset Id",
            "type": "string"
          },
          "deleted_above": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/RecordRef"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only on a single-record fetch of a live record: the deleted records directly above it, topmost first. Not empty means it is out of sight (nothing above it lists it); POST /records/{id}/restore-above brings them back.",
            "title": "Deleted Above"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When this record was soft-deleted. Null means live.",
            "title": "Deleted At"
          },
          "deleted_fields": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/DeletedFieldValue"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Values this record still holds for fields that have been deleted from its schema. Nothing is lost: restoring the field (`POST /schemas/{schema_name}/fields/{id}/restore`) puts each back in `data`. Null when there are none.",
            "title": "Deleted Fields"
          },
          "derived": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only when 'columns' were requested: the requested columns this record's own 'data' can't answer -- fields inherited from an ancestor record, and 'ref_field.target_field' joins -- keyed by column.",
            "title": "Derived"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "natural_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Natural Name"
          },
          "parent_record_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Record Id"
          },
          "reference_collections": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "For reference/reference_list targets that live in a different collection (a global one), the target's id mapped to that collection's name. Targets in the record's own collection are left out.",
            "title": "Reference Collections"
          },
          "reference_labels": {
            "anyOf": [
              {
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "For every reference/reference_list value on this record, the target record's id mapped to its natural_name (null if the target has none). Lets clients render a reference as a link with a readable label without a lookup per value.",
            "title": "Reference Labels"
          },
          "schema_name": {
            "title": "Schema Name",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "dataset_id",
          "schema_name",
          "parent_record_id",
          "data",
          "natural_name",
          "created_at",
          "updated_at"
        ],
        "title": "RecordResponse",
        "type": "object"
      },
      "RecordUseResponse": {
        "properties": {
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The collection it is in.",
            "title": "Collection"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "name": {
            "description": "The record's name, as the app shows it.",
            "title": "Name",
            "type": "string"
          },
          "trail": {
            "description": "The names of the records above it, outermost first.",
            "items": {
              "type": "string"
            },
            "title": "Trail",
            "type": "array"
          }
        },
        "required": [
          "id",
          "name",
          "collection",
          "trail"
        ],
        "title": "RecordUseResponse",
        "type": "object"
      },
      "ReferrerGroupResponse": {
        "properties": {
          "collection": {
            "description": "Name of that collection.",
            "title": "Collection",
            "type": "string"
          },
          "count": {
            "description": "Live records of this schema, in this collection, referencing it.",
            "title": "Count",
            "type": "integer"
          },
          "dataset_id": {
            "description": "Id of the collection the referrers live in.",
            "title": "Dataset Id",
            "type": "string"
          },
          "dtype": {
            "description": "'reference' or 'reference_list'.",
            "title": "Dtype",
            "type": "string"
          },
          "field_name": {
            "description": "The reference field that points at the record.",
            "title": "Field Name",
            "type": "string"
          },
          "schema_name": {
            "description": "Schema of the referring records; it owns the field.",
            "title": "Schema Name",
            "type": "string"
          }
        },
        "required": [
          "dataset_id",
          "collection",
          "schema_name",
          "field_name",
          "dtype",
          "count"
        ],
        "title": "ReferrerGroupResponse",
        "type": "object"
      },
      "RemoteConnectRequest": {
        "properties": {
          "invite": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The invite the authority's admin gave. Leave out when this computer has joined that address before (trying a connect again).",
            "title": "Invite"
          },
          "url": {
            "description": "The authority's address.",
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "title": "RemoteConnectRequest",
        "type": "object"
      },
      "RemoteConnectResponse": {
        "properties": {
          "mode": {
            "description": "joined (became a copy), seeded (filled an empty authority), empty (both empty) or resumed (already the same project).",
            "title": "Mode",
            "type": "string"
          }
        },
        "required": [
          "mode"
        ],
        "title": "RemoteConnectResponse",
        "type": "object"
      },
      "RemoteStatusResponse": {
        "properties": {
          "configured": {
            "description": "Whether this project follows an authority.",
            "title": "Configured",
            "type": "boolean"
          },
          "connect_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the last connect started here failed.",
            "title": "Connect Error"
          },
          "connecting": {
            "default": false,
            "description": "A connect started here is still running.",
            "title": "Connecting",
            "type": "boolean"
          },
          "download_files": {
            "description": "Which files this device keeps a copy of: all, or opened.",
            "title": "Download Files",
            "type": "string"
          },
          "files_to_fetch": {
            "description": "Files records here cite that aren't on this computer yet.",
            "title": "Files To Fetch",
            "type": "integer"
          },
          "interval_seconds": {
            "description": "How often it looks for changes; 0 means only when asked.",
            "title": "Interval Seconds",
            "type": "integer"
          },
          "last_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the last attempt failed, if it did.",
            "title": "Last Error"
          },
          "last_error_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Error At"
          },
          "last_result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SyncResultResponse"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the last sync run by this server did; null after a restart or before the first one."
          },
          "last_synced_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Synced At"
          },
          "open_conflicts": {
            "description": "Values that did not go in as made.",
            "title": "Open Conflicts",
            "type": "integer"
          },
          "paused": {
            "description": "The schedule is stopped; Sync now still works.",
            "title": "Paused",
            "type": "boolean"
          },
          "pending": {
            "description": "Changes made here that have not been sent.",
            "title": "Pending",
            "type": "integer"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SyncProgressResponse"
              },
              {
                "type": "null"
              }
            ],
            "description": "How far a long step has got while one runs here: copying the project from the authority, filling an empty one, or fetching the history from before joining."
          },
          "project_id": {
            "title": "Project Id",
            "type": "string"
          },
          "remote": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The authority's address.",
            "title": "Remote"
          },
          "running": {
            "description": "A sync is in progress right now.",
            "title": "Running",
            "type": "boolean"
          },
          "serving": {
            "description": "This project is itself an authority.",
            "title": "Serving",
            "type": "boolean"
          }
        },
        "required": [
          "configured",
          "remote",
          "project_id",
          "paused",
          "interval_seconds",
          "serving",
          "pending",
          "open_conflicts",
          "last_synced_at",
          "last_error",
          "last_error_at",
          "running",
          "download_files",
          "files_to_fetch"
        ],
        "title": "RemoteStatusResponse",
        "type": "object"
      },
      "RemoteUpdateRequest": {
        "properties": {
          "download_files": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Keep a copy of every file (all), or only of files opened or exported (opened).",
            "title": "Download Files"
          },
          "interval_seconds": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Seconds between looks for changes; 0 = never (only when asked).",
            "title": "Interval Seconds"
          },
          "paused": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Stop or start the schedule.",
            "title": "Paused"
          }
        },
        "title": "RemoteUpdateRequest",
        "type": "object"
      },
      "RemoveExportsRequest": {
        "properties": {
          "paths": {
            "description": "Export folders to delete, as listed by GET /file-access/exports.",
            "items": {
              "type": "string"
            },
            "title": "Paths",
            "type": "array"
          }
        },
        "required": [
          "paths"
        ],
        "title": "RemoveExportsRequest",
        "type": "object"
      },
      "ReopenRequest": {
        "properties": {
          "ids": {
            "description": "Conflicts to open again.",
            "items": {
              "type": "string"
            },
            "title": "Ids",
            "type": "array"
          }
        },
        "required": [
          "ids"
        ],
        "title": "ReopenRequest",
        "type": "object"
      },
      "ReopenResponse": {
        "properties": {
          "reopened": {
            "description": "How many were opened again. Only conflicts settled with `theirs` can be: that changed nothing, so it can be taken back.",
            "title": "Reopened",
            "type": "integer"
          }
        },
        "required": [
          "reopened"
        ],
        "title": "ReopenResponse",
        "type": "object"
      },
      "ReorderFieldsRequest": {
        "properties": {
          "order": {
            "items": {
              "type": "string"
            },
            "title": "Order",
            "type": "array"
          }
        },
        "required": [
          "order"
        ],
        "title": "ReorderFieldsRequest",
        "type": "object"
      },
      "RerunJobsRequest": {
        "properties": {
          "filter": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Instead of ids: repeat every run this filter matches (the same filter tree as GET /jobs, at most 1000 runs).",
            "title": "Filter"
          },
          "ids": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "maxItems": 200,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ids of the runs to repeat. Each is queued as a new run.",
            "title": "Ids"
          }
        },
        "title": "RerunJobsRequest",
        "type": "object"
      },
      "RerunJobsResponse": {
        "properties": {
          "skipped": {
            "description": "Runs that could not be repeated, such as one whose record has since been deleted.",
            "items": {
              "$ref": "#/components/schemas/SkippedJob"
            },
            "title": "Skipped",
            "type": "array"
          },
          "started": {
            "description": "The new runs that were queued, in the order asked.",
            "items": {
              "$ref": "#/components/schemas/WorkflowJobResponse"
            },
            "title": "Started",
            "type": "array"
          }
        },
        "required": [
          "started",
          "skipped"
        ],
        "title": "RerunJobsResponse",
        "type": "object"
      },
      "ResolveFailure": {
        "properties": {
          "id": {
            "title": "Id",
            "type": "string"
          },
          "message": {
            "title": "Message",
            "type": "string"
          }
        },
        "required": [
          "id",
          "message"
        ],
        "title": "ResolveFailure",
        "type": "object"
      },
      "ResolveManyRequest": {
        "properties": {
          "dry_run": {
            "default": false,
            "description": "Only count what would be settled; change nothing.",
            "title": "Dry Run",
            "type": "boolean"
          },
          "force": {
            "default": false,
            "description": "For `mine`: put values back even where the record's value changed since.",
            "title": "Force",
            "type": "boolean"
          },
          "ids": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these conflicts. Omit for all that match.",
            "title": "Ids"
          },
          "kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only this kind: conflict, rejected or edit_vs_delete.",
            "title": "Kind"
          },
          "record_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only conflicts about this record.",
            "title": "Record Id"
          },
          "take": {
            "description": "How to settle each one: `theirs`, `mine`, `delete` or `retry` (see the single resolve). `value` is not offered: it needs a value each.",
            "title": "Take",
            "type": "string"
          }
        },
        "required": [
          "take"
        ],
        "title": "ResolveManyRequest",
        "type": "object"
      },
      "ResolveManyResponse": {
        "properties": {
          "done": {
            "description": "Settled (with `dry_run`, how many would be).",
            "title": "Done",
            "type": "integer"
          },
          "failed": {
            "description": "Left open because they failed their checks; the rest were settled.",
            "items": {
              "$ref": "#/components/schemas/ResolveFailure"
            },
            "title": "Failed",
            "type": "array"
          },
          "not_offered": {
            "description": "Left open because they don't offer that way of settling.",
            "title": "Not Offered",
            "type": "integer"
          },
          "settled_ids": {
            "description": "Which were settled (empty for `dry_run`); `reopen` takes them back if the way was `theirs`.",
            "items": {
              "type": "string"
            },
            "title": "Settled Ids",
            "type": "array"
          }
        },
        "required": [
          "done",
          "settled_ids",
          "not_offered",
          "failed"
        ],
        "title": "ResolveManyResponse",
        "type": "object"
      },
      "ResolveRequest": {
        "properties": {
          "force": {
            "default": false,
            "description": "Put the value back even though the record's value changed since the conflict was recorded.",
            "title": "Force",
            "type": "boolean"
          },
          "take": {
            "description": "`theirs` keeps what the authority has (or lets a refused change go); `mine` puts your value back as a new edit; `value` puts the one in `value`; `delete` deletes a record that was deleted there; `retry` sends a refused change again from the record as it is now; `restore_above` brings back the deleted records a refused record sits under, then sends it again; `edited` closes a clash because the field was just set by hand on the record.",
            "title": "Take",
            "type": "string"
          },
          "value": {
            "description": "The value, for `take: value`.",
            "title": "Value"
          }
        },
        "required": [
          "take"
        ],
        "title": "ResolveRequest",
        "type": "object"
      },
      "RestoreAllPlanResponse": {
        "properties": {
          "blocked": {
            "description": "Matched, but under something deleted that is not in the set (for a field, also one whose name has since been taken).",
            "title": "Blocked",
            "type": "integer"
          },
          "collections": {
            "description": "Deleted collections matched.",
            "title": "Collections",
            "type": "integer"
          },
          "fields": {
            "default": 0,
            "description": "Deleted fields matched.",
            "title": "Fields",
            "type": "integer"
          },
          "records": {
            "description": "Deleted records matched.",
            "title": "Records",
            "type": "integer"
          },
          "restores": {
            "description": "Records that would be live afterwards, counting what came back with each, once.",
            "title": "Restores",
            "type": "integer"
          },
          "schemas": {
            "description": "Deleted schemas matched.",
            "title": "Schemas",
            "type": "integer"
          },
          "things": {
            "description": "All of the above.",
            "title": "Things",
            "type": "integer"
          },
          "truncated": {
            "description": "More matched than were looked at.",
            "title": "Truncated",
            "type": "boolean"
          }
        },
        "required": [
          "collections",
          "schemas",
          "records",
          "things",
          "restores",
          "blocked",
          "truncated"
        ],
        "title": "RestoreAllPlanResponse",
        "type": "object"
      },
      "RestoreAllRequest": {
        "properties": {
          "batch": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only what this batch deleted: the id of a bulk delete (a record and everything beneath it) from `/audit/events`.",
            "title": "Batch"
          },
          "filter": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The history filter tree whose matches are restored (the one `GET /audit/events` takes), or null for everything deleted.",
            "title": "Filter"
          },
          "q": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Text the changes must contain.",
            "title": "Q"
          }
        },
        "title": "RestoreAllRequest",
        "type": "object"
      },
      "RestoreAllResultResponse": {
        "properties": {
          "blocked": {
            "description": "Left deleted: a parent is deleted and not in the set, or a field's name has been taken.",
            "title": "Blocked",
            "type": "integer"
          },
          "records": {
            "description": "Records that came back in all.",
            "title": "Records",
            "type": "integer"
          },
          "restored": {
            "description": "Things brought back.",
            "title": "Restored",
            "type": "integer"
          }
        },
        "required": [
          "restored",
          "records",
          "blocked"
        ],
        "title": "RestoreAllResultResponse",
        "type": "object"
      },
      "RestoreConflictResponse": {
        "properties": {
          "existing_id": {
            "description": "The live record that now holds the same unique values.",
            "title": "Existing Id",
            "type": "string"
          },
          "existing_name": {
            "title": "Existing Name",
            "type": "string"
          },
          "fields": {
            "description": "The unique key's field names.",
            "items": {
              "type": "string"
            },
            "title": "Fields",
            "type": "array"
          },
          "message": {
            "description": "The whole explanation, in plain words.",
            "title": "Message",
            "type": "string"
          },
          "record_id": {
            "description": "The record that can't come back.",
            "title": "Record Id",
            "type": "string"
          },
          "record_name": {
            "title": "Record Name",
            "type": "string"
          }
        },
        "required": [
          "record_id",
          "record_name",
          "existing_id",
          "existing_name",
          "fields",
          "message"
        ],
        "title": "RestoreConflictResponse",
        "type": "object"
      },
      "RestorePlanResponse": {
        "properties": {
          "blocked": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why it can't be restored yet, in plain words. Null when it can.",
            "title": "Blocked"
          },
          "blocked_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BlockerResponse"
              },
              {
                "type": "null"
              }
            ],
            "description": "The deleted collection, schema or record that must be restored first. Null when it can be restored now."
          },
          "can_restore": {
            "title": "Can Restore",
            "type": "boolean"
          },
          "collection": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "For a record: the collection it will be in.",
            "title": "Collection"
          },
          "collection_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Collection Id"
          },
          "conflict": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/RestoreConflictResponse"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when another record has taken the values of a uniqueness key while this one was deleted: restoring is refused until that record is changed or deleted."
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it was deleted.",
            "title": "Deleted At"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "description": "record, collection, schema or field.",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "parents_needed": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "For a record held back only by deleted records above it: how many of them. `POST .../restore?with_parents=true` brings each back by itself (not what was deleted alongside it), so just this record (`&only_this=true`) comes back as `parents_needed + 1` records and its deleted siblings stay deleted. Null otherwise.",
            "title": "Parents Needed"
          },
          "records": {
            "description": "How many records come back: those deleted together with this, the record itself included when it is one. Never something deleted on its own earlier.",
            "title": "Records",
            "type": "integer"
          },
          "schema_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "For a field: the schema it belongs to.",
            "title": "Schema Name"
          }
        },
        "required": [
          "kind",
          "id",
          "name",
          "records",
          "can_restore"
        ],
        "title": "RestorePlanResponse",
        "type": "object"
      },
      "RestoreResult": {
        "properties": {
          "datasets": {
            "title": "Datasets",
            "type": "integer"
          },
          "plugins": {
            "title": "Plugins",
            "type": "integer"
          },
          "records_restored": {
            "title": "Records Restored",
            "type": "integer"
          },
          "records_total": {
            "title": "Records Total",
            "type": "integer"
          },
          "schemas": {
            "title": "Schemas",
            "type": "integer"
          },
          "workflows": {
            "title": "Workflows",
            "type": "integer"
          }
        },
        "required": [
          "schemas",
          "datasets",
          "records_restored",
          "records_total",
          "workflows",
          "plugins"
        ],
        "title": "RestoreResult",
        "type": "object"
      },
      "RestoreSelectedRequest": {
        "properties": {
          "ids": {
            "description": "The deleted records to restore.",
            "items": {
              "type": "string"
            },
            "maxItems": 5000,
            "title": "Ids",
            "type": "array"
          },
          "with_parents": {
            "default": true,
            "description": "Also restore the deleted records above a chosen one, each by itself. Without it, a record under a deleted record is left.",
            "title": "With Parents",
            "type": "boolean"
          }
        },
        "required": [
          "ids"
        ],
        "title": "RestoreSelectedRequest",
        "type": "object"
      },
      "RestoreSelectedResponse": {
        "properties": {
          "came_back": {
            "description": "Records live again in all, counting the parents brought back.",
            "title": "Came Back",
            "type": "integer"
          },
          "left": {
            "description": "Chosen records still deleted, and why not.",
            "title": "Left",
            "type": "integer"
          },
          "restored": {
            "description": "Chosen records that came back.",
            "title": "Restored",
            "type": "integer"
          }
        },
        "required": [
          "restored",
          "came_back",
          "left"
        ],
        "title": "RestoreSelectedResponse",
        "type": "object"
      },
      "RestrictionDescriptorResponse": {
        "properties": {
          "control": {
            "description": "Which editor to show: number, integer, bytes, choices, accept, filename_template, schema, timezone, date_bound, datetime_bound, unit, precision, geometry_types or bbox.",
            "title": "Control",
            "type": "string"
          },
          "help": {
            "description": "One sentence of guidance; may be empty.",
            "title": "Help",
            "type": "string"
          },
          "key": {
            "description": "Key in a field's `restrictions` dict.",
            "title": "Key",
            "type": "string"
          },
          "label": {
            "description": "Name shown beside the control.",
            "title": "Label",
            "type": "string"
          }
        },
        "required": [
          "key",
          "label",
          "control",
          "help"
        ],
        "title": "RestrictionDescriptorResponse",
        "type": "object"
      },
      "RetentionReportResponse": {
        "properties": {
          "anything": {
            "title": "Anything",
            "type": "boolean"
          },
          "audit_batches": {
            "title": "Audit Batches",
            "type": "integer"
          },
          "audit_entries": {
            "title": "Audit Entries",
            "type": "integer"
          },
          "audit_kept_first_and_last": {
            "default": 0,
            "description": "Older history kept because it is a thing's creation or its latest entry, which are kept however old.",
            "title": "Audit Kept First And Last",
            "type": "integer"
          },
          "audit_kept_restorable": {
            "description": "Older history kept because it is about something that can still be restored.",
            "title": "Audit Kept Restorable",
            "type": "integer"
          },
          "audit_kept_unsynced": {
            "description": "Older history kept because it has not been synced yet.",
            "title": "Audit Kept Unsynced",
            "type": "integer"
          },
          "deleted_collections": {
            "title": "Deleted Collections",
            "type": "integer"
          },
          "deleted_records": {
            "title": "Deleted Records",
            "type": "integer"
          },
          "deleted_schemas": {
            "title": "Deleted Schemas",
            "type": "integer"
          },
          "dry_run": {
            "title": "Dry Run",
            "type": "boolean"
          },
          "run_steps": {
            "title": "Run Steps",
            "type": "integer"
          },
          "runs": {
            "title": "Runs",
            "type": "integer"
          },
          "skipped": {
            "description": "Deleted things that could not be removed, with why.",
            "items": {
              "type": "string"
            },
            "title": "Skipped",
            "type": "array"
          }
        },
        "required": [
          "dry_run",
          "deleted_records",
          "deleted_collections",
          "deleted_schemas",
          "skipped",
          "audit_entries",
          "audit_batches",
          "audit_kept_restorable",
          "audit_kept_unsynced",
          "runs",
          "run_steps",
          "anything"
        ],
        "title": "RetentionReportResponse",
        "type": "object"
      },
      "RetentionRunRequest": {
        "properties": {
          "audit_before": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Remove change history before this (not about anything that can still be restored, and with a remote, not yet pushed).",
            "title": "Audit Before"
          },
          "deleted_before": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Permanently delete everything deleted before this.",
            "title": "Deleted Before"
          },
          "dry_run": {
            "default": true,
            "description": "Only count what would be removed.",
            "title": "Dry Run",
            "type": "boolean"
          },
          "from_settings": {
            "default": false,
            "description": "Apply the retention settings (each kind left at keep-forever is left alone).",
            "title": "From Settings",
            "type": "boolean"
          },
          "runs_before": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Remove finished workflow runs, with their step logs, before this.",
            "title": "Runs Before"
          }
        },
        "title": "RetentionRunRequest",
        "type": "object"
      },
      "RetentionSettingsResponse": {
        "properties": {
          "audit_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Change history older than this many days is removed by a clean-up. Null keeps it forever.",
            "title": "Audit Days"
          },
          "auto_purge_deleted": {
            "description": "Whether a clean-up permanently deletes items deleted more than `purge_after_days` ago.",
            "title": "Auto Purge Deleted",
            "type": "boolean"
          },
          "purge_after_days": {
            "description": "Deleted items can be restored for this many days. A clean-up only deletes them permanently after that when `auto_purge_deleted` is on.",
            "title": "Purge After Days",
            "type": "integer"
          },
          "run_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Finished workflow runs, with their step logs, older than this many days are removed by a clean-up. Null keeps them forever.",
            "title": "Run Days"
          }
        },
        "required": [
          "purge_after_days",
          "auto_purge_deleted",
          "audit_days",
          "run_days"
        ],
        "title": "RetentionSettingsResponse",
        "type": "object"
      },
      "RevertFieldResponse": {
        "properties": {
          "current": {
            "description": "What the record holds now.",
            "title": "Current"
          },
          "dtype": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dtype"
          },
          "field": {
            "title": "Field",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason"
          },
          "status": {
            "description": "apply (still as the entry left it), conflict (edited since; reverted only when forced), same (already the older value) or skipped (cannot be put back; see reason).",
            "title": "Status",
            "type": "string"
          },
          "target": {
            "description": "What reverting would put back.",
            "title": "Target"
          }
        },
        "required": [
          "field",
          "status"
        ],
        "title": "RevertFieldResponse",
        "type": "object"
      },
      "RevertPlanResponse": {
        "properties": {
          "audit_id": {
            "title": "Audit Id",
            "type": "string"
          },
          "blocked": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the entry can't be reverted at all.",
            "title": "Blocked"
          },
          "blocker": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BlockerResponse"
              },
              {
                "type": "null"
              }
            ],
            "description": "When a deleted record can't come back yet, what to restore first."
          },
          "can_apply": {
            "title": "Can Apply",
            "type": "boolean"
          },
          "entity_id": {
            "title": "Entity Id",
            "type": "string"
          },
          "entity_type": {
            "title": "Entity Type",
            "type": "string"
          },
          "fields": {
            "description": "Per-field plan, for an update.",
            "items": {
              "$ref": "#/components/schemas/RevertFieldResponse"
            },
            "title": "Fields",
            "type": "array"
          },
          "has_conflicts": {
            "title": "Has Conflicts",
            "type": "boolean"
          },
          "kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "update (put fields back), restore (undo a delete) or delete (undo a create). Null when nothing can be reverted.",
            "title": "Kind"
          }
        },
        "required": [
          "audit_id",
          "entity_type",
          "entity_id",
          "can_apply",
          "has_conflicts"
        ],
        "title": "RevertPlanResponse",
        "type": "object"
      },
      "RevertRequest": {
        "properties": {
          "fields": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only put these fields back. Omit to revert everything the entry changed.",
            "title": "Fields"
          },
          "force": {
            "default": false,
            "description": "Also overwrite fields that were edited since the entry.",
            "title": "Force",
            "type": "boolean"
          }
        },
        "title": "RevertRequest",
        "type": "object"
      },
      "RevertResultResponse": {
        "properties": {
          "applied": {
            "description": "Names of the fields that were put back (an update only).",
            "items": {
              "type": "string"
            },
            "title": "Applied",
            "type": "array"
          },
          "audit_id": {
            "title": "Audit Id",
            "type": "string"
          },
          "entity_id": {
            "title": "Entity Id",
            "type": "string"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          }
        },
        "required": [
          "audit_id",
          "entity_id",
          "kind",
          "applied"
        ],
        "title": "RevertResultResponse",
        "type": "object"
      },
      "RunFieldResponse": {
        "properties": {
          "choices": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Fixed choices, when there are any.",
            "title": "Choices"
          },
          "description": {
            "title": "Description",
            "type": "string"
          },
          "label": {
            "title": "Label",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "operators": {
            "description": "Operators a condition on it accepts.",
            "items": {
              "type": "string"
            },
            "title": "Operators",
            "type": "array"
          },
          "type": {
            "description": "string, enum, integer or datetime.",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "name",
          "label",
          "type",
          "description",
          "operators"
        ],
        "title": "RunFieldResponse",
        "type": "object"
      },
      "RunManyRequest": {
        "properties": {
          "record_ids": {
            "description": "Ids of the records to run the workflow on, one run each.",
            "items": {
              "type": "string"
            },
            "maxItems": 500,
            "minItems": 1,
            "title": "Record Ids",
            "type": "array"
          }
        },
        "required": [
          "record_ids"
        ],
        "title": "RunManyRequest",
        "type": "object"
      },
      "RunManyResponse": {
        "properties": {
          "skipped": {
            "description": "Records the workflow was not run on, each with why: not found, or not the schema the workflow is for.",
            "items": {
              "$ref": "#/components/schemas/SkippedJob"
            },
            "title": "Skipped",
            "type": "array"
          },
          "started": {
            "description": "The runs that were queued, in the order asked.",
            "items": {
              "$ref": "#/components/schemas/WorkflowJobResponse"
            },
            "title": "Started",
            "type": "array"
          }
        },
        "required": [
          "started",
          "skipped"
        ],
        "title": "RunManyResponse",
        "type": "object"
      },
      "SchemaDeleteImpactResponse": {
        "properties": {
          "child_schema_count": {
            "description": "Schemas that inherit from this one, directly or transitively \u2014 informational only, they are not deleted along with it, but their presence blocks a later purge.",
            "title": "Child Schema Count",
            "type": "integer"
          },
          "record_count": {
            "description": "Records typed by this schema itself, across every collection \u2014 deleted along with it.",
            "title": "Record Count",
            "type": "integer"
          }
        },
        "required": [
          "child_schema_count",
          "record_count"
        ],
        "title": "SchemaDeleteImpactResponse",
        "type": "object"
      },
      "SchemaResponse": {
        "properties": {
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When this schema was soft-deleted. Null means live.",
            "title": "Deleted At"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "display_template": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Template that names this schema's records; fields in braces, formats after a colon. Null means the first plain value is used.",
            "title": "Display Template"
          },
          "fields": {
            "items": {
              "$ref": "#/components/schemas/FieldResponse"
            },
            "title": "Fields",
            "type": "array"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Human-facing display name. Null means none was set \u2014 render the name title-cased instead.",
            "title": "Label"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "parent_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Id"
          },
          "unique_keys": {
            "description": "Uniqueness policies: each a list of this schema's own field names whose values no two records may share, within the same parent record (or the same collection, for a top-level record).",
            "items": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "title": "Unique Keys",
            "type": "array"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "parent_id",
          "fields"
        ],
        "title": "SchemaResponse",
        "type": "object"
      },
      "SetDbUrlRequest": {
        "properties": {
          "url": {
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "title": "SetDbUrlRequest",
        "type": "object"
      },
      "SetPlacementRequest": {
        "properties": {
          "on_unavailable": {
            "default": "spill",
            "description": "spill (default) or fail.",
            "title": "On Unavailable",
            "type": "string"
          },
          "volume": {
            "description": "Name of the volume that becomes the home.",
            "title": "Volume",
            "type": "string"
          }
        },
        "required": [
          "volume"
        ],
        "title": "SetPlacementRequest",
        "type": "object"
      },
      "SetQueueRequest": {
        "properties": {
          "queue": {
            "items": {
              "type": "string"
            },
            "title": "Queue",
            "type": "array"
          }
        },
        "required": [
          "queue"
        ],
        "title": "SetQueueRequest",
        "type": "object"
      },
      "SetUniqueKeysRequest": {
        "properties": {
          "keys": {
            "description": "The schema's complete list of uniqueness keys, replacing the current one; each key is a list of the schema's own field names. An empty list removes every policy.",
            "items": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "title": "Keys",
            "type": "array"
          }
        },
        "required": [
          "keys"
        ],
        "title": "SetUniqueKeysRequest",
        "type": "object"
      },
      "ShortcutResponse": {
        "properties": {
          "exists": {
            "description": "Whether the Desktop shortcut for this project is there.",
            "title": "Exists",
            "type": "boolean"
          },
          "path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where it is (or would be), when there is a Desktop.",
            "title": "Path"
          }
        },
        "required": [
          "exists"
        ],
        "title": "ShortcutResponse",
        "type": "object"
      },
      "SkippedJob": {
        "properties": {
          "id": {
            "title": "Id",
            "type": "string"
          },
          "reason": {
            "description": "Why this run could not be repeated.",
            "title": "Reason",
            "type": "string"
          }
        },
        "required": [
          "id",
          "reason"
        ],
        "title": "SkippedJob",
        "type": "object"
      },
      "StartUpdateRequest": {
        "properties": {
          "pre": {
            "default": false,
            "description": "Install a pre-release if it is the newest.",
            "title": "Pre",
            "type": "boolean"
          }
        },
        "title": "StartUpdateRequest",
        "type": "object"
      },
      "StartUpdateResponse": {
        "properties": {
          "restarting": {
            "description": "civex is closing to update and will start again; poll `/health` and reload when it answers.",
            "title": "Restarting",
            "type": "boolean"
          }
        },
        "required": [
          "restarting"
        ],
        "title": "StartUpdateResponse",
        "type": "object"
      },
      "StorageLocationResponse": {
        "properties": {
          "free_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Free space; null if unknown, and not read for network drives.",
            "title": "Free Bytes"
          },
          "kind": {
            "description": "project, home or drive.",
            "title": "Kind",
            "type": "string"
          },
          "label": {
            "title": "Label",
            "type": "string"
          },
          "network": {
            "description": "True for a drive that lives on another machine.",
            "title": "Network",
            "type": "boolean"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where a network drive really lives, e.g. nas:/export.",
            "title": "Source"
          },
          "total_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Bytes"
          }
        },
        "required": [
          "label",
          "path",
          "kind",
          "free_bytes",
          "total_bytes",
          "network",
          "source"
        ],
        "title": "StorageLocationResponse",
        "type": "object"
      },
      "StoredObjectResponse": {
        "properties": {
          "mtime": {
            "description": "Unix timestamp the object was written.",
            "title": "Mtime",
            "type": "number"
          },
          "sha256": {
            "description": "Content hash identifying the object.",
            "title": "Sha256",
            "type": "string"
          },
          "size": {
            "description": "Object size in bytes.",
            "title": "Size",
            "type": "integer"
          },
          "volume": {
            "description": "Volume the object was found on.",
            "title": "Volume",
            "type": "string"
          }
        },
        "required": [
          "sha256",
          "volume",
          "size",
          "mtime"
        ],
        "title": "StoredObjectResponse",
        "type": "object"
      },
      "SyncFeedResponse": {
        "properties": {
          "entries": {
            "description": "Changes past `after`, in the authority's order, each with its `hub_seq` and whether it was `superseded` by a later settled state.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Entries",
            "type": "array"
          },
          "head_seq": {
            "title": "Head Seq",
            "type": "integer"
          },
          "more": {
            "description": "There are more past this page.",
            "title": "More",
            "type": "boolean"
          }
        },
        "required": [
          "entries",
          "head_seq",
          "more"
        ],
        "title": "SyncFeedResponse",
        "type": "object"
      },
      "SyncFilesRequest": {
        "properties": {
          "sha256": {
            "description": "Content hashes of files the device holds.",
            "items": {
              "type": "string"
            },
            "maxItems": 5000,
            "title": "Sha256",
            "type": "array"
          }
        },
        "required": [
          "sha256"
        ],
        "title": "SyncFilesRequest",
        "type": "object"
      },
      "SyncFilesResponse": {
        "properties": {
          "missing": {
            "description": "Those the authority does not have yet.",
            "items": {
              "type": "string"
            },
            "title": "Missing",
            "type": "array"
          }
        },
        "required": [
          "missing"
        ],
        "title": "SyncFilesResponse",
        "type": "object"
      },
      "SyncHelloResponse": {
        "properties": {
          "capabilities": {
            "description": "Optional features it has, by name. Adding one is not a protocol change.",
            "items": {
              "type": "string"
            },
            "title": "Capabilities",
            "type": "array"
          },
          "counts": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "How many of each kind it holds, deleted ones included, so a device copying it can show how far along it is.",
            "title": "Counts",
            "type": "object"
          },
          "device_name": {
            "description": "What the token used is called here.",
            "title": "Device Name",
            "type": "string"
          },
          "empty": {
            "description": "True when it holds none of the project's things yet (an empty authority can be filled from a project that has data).",
            "title": "Empty",
            "type": "boolean"
          },
          "feed_floor": {
            "default": 0,
            "description": "The highest number the feed no longer holds (history pruned here). A device whose cursor is below it copies the project again.",
            "title": "Feed Floor",
            "type": "integer"
          },
          "head_seq": {
            "description": "The latest number the authority has handed out.",
            "title": "Head Seq",
            "type": "integer"
          },
          "project_id": {
            "description": "The project's id, shared by every copy.",
            "title": "Project Id",
            "type": "string"
          },
          "protocol_max": {
            "description": "The newest sync protocol it speaks.",
            "title": "Protocol Max",
            "type": "integer"
          },
          "protocol_min": {
            "description": "The oldest sync protocol it speaks.",
            "title": "Protocol Min",
            "type": "integer"
          },
          "protocol_version": {
            "description": "The sync protocol this server and the calling device agreed on.",
            "title": "Protocol Version",
            "type": "integer"
          },
          "seeded_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The device that put the first data in, if any.",
            "title": "Seeded By"
          },
          "server_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The civex release it runs.",
            "title": "Server Version"
          }
        },
        "required": [
          "protocol_version",
          "project_id",
          "head_seq",
          "empty",
          "device_name",
          "protocol_min",
          "protocol_max"
        ],
        "title": "SyncHelloResponse",
        "type": "object"
      },
      "SyncJoinRequest": {
        "properties": {
          "device_id": {
            "description": "This device's id (a UUID).",
            "title": "Device Id",
            "type": "string"
          },
          "invite": {
            "description": "The invite code the authority's admin gave.",
            "title": "Invite",
            "type": "string"
          },
          "public_key": {
            "description": "This device's Ed25519 public key, base64 of its 32 bytes.",
            "title": "Public Key",
            "type": "string"
          }
        },
        "required": [
          "invite",
          "device_id",
          "public_key"
        ],
        "title": "SyncJoinRequest",
        "type": "object"
      },
      "SyncJoinResponse": {
        "properties": {
          "authority_key": {
            "description": "The authority's public key: it signs its answers to sign-ins.",
            "title": "Authority Key",
            "type": "string"
          },
          "device_name": {
            "description": "What the device was invited as.",
            "title": "Device Name",
            "type": "string"
          },
          "project_id": {
            "description": "The project's id, shared by every copy.",
            "title": "Project Id",
            "type": "string"
          }
        },
        "required": [
          "project_id",
          "authority_key",
          "device_name"
        ],
        "title": "SyncJoinResponse",
        "type": "object"
      },
      "SyncOpResponse": {
        "properties": {
          "conflicts": {
            "description": "Values that did not go in as made: field, yours, theirs, kind.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Conflicts",
            "type": "array"
          },
          "hub_seq": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the authority numbered it, once taken.",
            "title": "Hub Seq"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message"
          },
          "op_id": {
            "title": "Op Id",
            "type": "string"
          },
          "status": {
            "description": "applied, merged, conflict, duplicate, rejected or deferred (deferred: not taken yet; send it again).",
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "op_id",
          "status"
        ],
        "title": "SyncOpResponse",
        "type": "object"
      },
      "SyncProgressResponse": {
        "properties": {
          "bytes_done": {
            "default": 0,
            "description": "Downloading files: bytes so far.",
            "title": "Bytes Done",
            "type": "integer"
          },
          "done": {
            "description": "Things (or history entries) done so far.",
            "title": "Done",
            "type": "integer"
          },
          "kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The kind of thing it is on (schema, record...).",
            "title": "Kind"
          },
          "phase": {
            "description": "copying, filling or history.",
            "title": "Phase",
            "type": "string"
          },
          "rate": {
            "default": 0.0,
            "description": "Downloading files: bytes per second, lately.",
            "title": "Rate",
            "type": "number"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Out of how many; null when not known.",
            "title": "Total"
          }
        },
        "required": [
          "phase",
          "done",
          "total"
        ],
        "title": "SyncProgressResponse",
        "type": "object"
      },
      "SyncPushRequest": {
        "properties": {
          "entries": {
            "description": "Changes made on the device, oldest first: history entries with their snapshots. Each is identified by its id, so sending one twice is harmless.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "maxItems": 500,
            "title": "Entries",
            "type": "array"
          }
        },
        "required": [
          "entries"
        ],
        "title": "SyncPushRequest",
        "type": "object"
      },
      "SyncPushResponse": {
        "properties": {
          "head_seq": {
            "title": "Head Seq",
            "type": "integer"
          },
          "results": {
            "description": "One answer per change, in order. Fewer than were sent means the rest were held back behind one that has to wait.",
            "items": {
              "$ref": "#/components/schemas/SyncOpResponse"
            },
            "title": "Results",
            "type": "array"
          }
        },
        "required": [
          "results",
          "head_seq"
        ],
        "title": "SyncPushResponse",
        "type": "object"
      },
      "SyncResultResponse": {
        "properties": {
          "conflicts": {
            "description": "Values that did not go in as made.",
            "title": "Conflicts",
            "type": "integer"
          },
          "files_sent": {
            "title": "Files Sent",
            "type": "integer"
          },
          "pulled": {
            "description": "Changes from others brought in.",
            "title": "Pulled",
            "type": "integer"
          },
          "pushed": {
            "description": "Changes of this project's that were sent.",
            "title": "Pushed",
            "type": "integer"
          },
          "rejected": {
            "description": "Changes the authority refused.",
            "title": "Rejected",
            "type": "integer"
          }
        },
        "required": [
          "pulled",
          "pushed",
          "files_sent",
          "conflicts",
          "rejected"
        ],
        "title": "SyncResultResponse",
        "type": "object"
      },
      "SyncSessionRequest": {
        "properties": {
          "at": {
            "description": "Now, in unix seconds, as the device's clock says.",
            "title": "At",
            "type": "integer"
          },
          "device_id": {
            "description": "The device signing in.",
            "title": "Device Id",
            "type": "string"
          },
          "signature": {
            "description": "The device's signature over the session request (the authority's key, the device id and `at`).",
            "title": "Signature",
            "type": "string"
          }
        },
        "required": [
          "device_id",
          "at",
          "signature"
        ],
        "title": "SyncSessionRequest",
        "type": "object"
      },
      "SyncSessionResponse": {
        "properties": {
          "expires_at": {
            "description": "When the token stops working, unix seconds.",
            "title": "Expires At",
            "type": "integer"
          },
          "signature": {
            "description": "The authority's signature over its answer to this request.",
            "title": "Signature",
            "type": "string"
          },
          "token": {
            "description": "Send as `Authorization: Bearer` until it expires.",
            "title": "Token",
            "type": "string"
          }
        },
        "required": [
          "token",
          "expires_at",
          "signature"
        ],
        "title": "SyncSessionResponse",
        "type": "object"
      },
      "SyncSnapshotResponse": {
        "properties": {
          "head_seq": {
            "description": "Taken before reading: what changes meanwhile is in the feed past it.",
            "title": "Head Seq",
            "type": "integer"
          },
          "items": {
            "description": "Things of this kind as they are now, in the shape a history entry stores them.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Items",
            "type": "array"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          },
          "more": {
            "title": "More",
            "type": "boolean"
          },
          "next": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `after` for the next page; null on the last page.",
            "title": "Next"
          }
        },
        "required": [
          "kind",
          "items",
          "more",
          "head_seq"
        ],
        "title": "SyncSnapshotResponse",
        "type": "object"
      },
      "TableRequest": {
        "description": "A table made beside the files (or instead of them). What it is comes from\nthree choices: which records are its rows ('kind'), where it is written\n('where': once at the top, or in the folder of each record of a kind) and its\ncolumns. Leave 'kind' out for one table per kind of record the export holds.",
        "properties": {
          "columns": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which columns, in order: field names, 'ref_field.target_field' joins, or 'id', 'schema', 'created_at', 'updated_at'. Omit for the id and every field. When the records are of several kinds, each kind's table takes the columns it has.",
            "title": "Columns"
          },
          "format": {
            "default": "csv",
            "description": "The file format of the table.",
            "enum": [
              "csv",
              "tsv",
              "xlsx",
              "json",
              "jsonl"
            ],
            "title": "Format",
            "type": "string"
          },
          "kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The schema whose records are the rows: the records the export takes, the ones above them, and (with 'below') the ones beneath. Omit for one table per kind the export holds, written at the top.",
            "title": "Kind"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The file's name without its extension. With 'kind' it is a template over the folder's record ('{schema}', '{id}' and its fields); without, the name when there is just one table. Omit to name it for what it holds ('Selections') or, for a record's own fields, 'Metadata'.",
            "title": "Name"
          },
          "shape": {
            "default": "rows",
            "description": "'rows': a row per record. 'fields': the fields of one record as field/value pairs (a metadata sheet); needs 'where' to equal 'kind'.",
            "enum": [
              "rows",
              "fields"
            ],
            "title": "Shape",
            "type": "string"
          },
          "skip_empty": {
            "default": true,
            "description": "False also writes a table (just its header) in a folder that has no rows.",
            "title": "Skip Empty",
            "type": "boolean"
          },
          "where": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Write the table in the folder of each record of this schema, holding the 'kind' records that are that record or beneath it. The same as 'kind' gives each record its own table. Omit to write it once, at the top. Needs the 'tree' layout.",
            "title": "Where"
          }
        },
        "title": "TableRequest",
        "type": "object"
      },
      "TargetShareResponse": {
        "properties": {
          "bytes": {
            "title": "Bytes",
            "type": "integer"
          },
          "files": {
            "description": "About how many files would go to this target.",
            "title": "Files",
            "type": "integer"
          },
          "free_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Room the target has; null if it can't be read now.",
            "title": "Free Bytes"
          },
          "volume": {
            "title": "Volume",
            "type": "string"
          }
        },
        "required": [
          "volume",
          "files",
          "bytes",
          "free_bytes"
        ],
        "title": "TargetShareResponse",
        "type": "object"
      },
      "TokenUsageBucketResponse": {
        "properties": {
          "bucket": {
            "title": "Bucket",
            "type": "string"
          },
          "input_tokens": {
            "title": "Input Tokens",
            "type": "integer"
          },
          "model": {
            "title": "Model",
            "type": "string"
          },
          "output_tokens": {
            "title": "Output Tokens",
            "type": "integer"
          },
          "provider": {
            "title": "Provider",
            "type": "string"
          }
        },
        "required": [
          "bucket",
          "provider",
          "model",
          "input_tokens",
          "output_tokens"
        ],
        "title": "TokenUsageBucketResponse",
        "type": "object"
      },
      "ToolCallMessage": {
        "description": "A tool call + its result, as originally exchanged with the model.\n\nThe frontend keeps this alongside plain text turns in conversation history\nand resends it verbatim on every later request, so a tool call made (and\nits result received) in an earlier turn is not lost across separate HTTP\nrequests -- see civex.services.ai.history's _iter_turns()/\n_history_to_anthropic()/_history_to_openai().",
        "properties": {
          "id": {
            "title": "Id",
            "type": "string"
          },
          "input": {
            "additionalProperties": true,
            "title": "Input",
            "type": "object"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "result": {
            "title": "Result",
            "type": "string"
          },
          "role": {
            "const": "tool_call",
            "default": "tool_call",
            "title": "Role",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "input",
          "result"
        ],
        "title": "ToolCallMessage",
        "type": "object"
      },
      "TransferFailureResponse": {
        "properties": {
          "reason": {
            "title": "Reason",
            "type": "string"
          },
          "sha256": {
            "title": "Sha256",
            "type": "string"
          },
          "volume": {
            "description": "Where the file is (and stays).",
            "title": "Volume",
            "type": "string"
          }
        },
        "required": [
          "sha256",
          "volume",
          "reason"
        ],
        "title": "TransferFailureResponse",
        "type": "object"
      },
      "TransferPlanResponse": {
        "properties": {
          "already_there": {
            "description": "Files already on a target, left alone.",
            "title": "Already There",
            "type": "integer"
          },
          "bytes": {
            "title": "Bytes",
            "type": "integer"
          },
          "can_proceed": {
            "title": "Can Proceed",
            "type": "boolean"
          },
          "copied": {
            "description": "Of `files`, those copied rather than moved: the drive they come from is the home of another collection that uses them, and keeps its copy.",
            "title": "Copied",
            "type": "integer"
          },
          "copied_bytes": {
            "title": "Copied Bytes",
            "type": "integer"
          },
          "files": {
            "description": "Files that would be moved (from the catalog, so close, not exact).",
            "title": "Files",
            "type": "integer"
          },
          "problems": {
            "description": "Reasons the transfer can't start.",
            "items": {
              "type": "string"
            },
            "title": "Problems",
            "type": "array"
          },
          "targets": {
            "items": {
              "$ref": "#/components/schemas/TargetShareResponse"
            },
            "title": "Targets",
            "type": "array"
          },
          "warnings": {
            "description": "Things worth knowing; they don't stop it.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "files",
          "bytes",
          "already_there",
          "copied",
          "copied_bytes",
          "targets",
          "problems",
          "warnings",
          "can_proceed"
        ],
        "title": "TransferPlanResponse",
        "type": "object"
      },
      "TransferProgressResponse": {
        "properties": {
          "bytes_done": {
            "title": "Bytes Done",
            "type": "integer"
          },
          "bytes_total": {
            "title": "Bytes Total",
            "type": "integer"
          },
          "current": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The file being copied (a hash prefix), if any.",
            "title": "Current"
          },
          "current_bytes": {
            "description": "Bytes of the current file copied so far; add to bytes_done for a smooth bar.",
            "title": "Current Bytes",
            "type": "integer"
          },
          "current_total": {
            "title": "Current Total",
            "type": "integer"
          },
          "eta_seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Eta Seconds"
          },
          "files_done": {
            "title": "Files Done",
            "type": "integer"
          },
          "files_failed": {
            "title": "Files Failed",
            "type": "integer"
          },
          "files_skipped": {
            "description": "Already on a target.",
            "title": "Files Skipped",
            "type": "integer"
          },
          "files_total": {
            "title": "Files Total",
            "type": "integer"
          },
          "message": {
            "title": "Message",
            "type": "string"
          },
          "rate_bytes_per_second": {
            "title": "Rate Bytes Per Second",
            "type": "number"
          }
        },
        "required": [
          "files_total",
          "files_done",
          "files_skipped",
          "files_failed",
          "bytes_total",
          "bytes_done",
          "current",
          "current_bytes",
          "current_total",
          "rate_bytes_per_second",
          "eta_seconds",
          "message"
        ],
        "title": "TransferProgressResponse",
        "type": "object"
      },
      "TransferRequest": {
        "properties": {
          "collection_ids": {
            "description": "consolidate: ids of the collections to move.",
            "items": {
              "type": "string"
            },
            "title": "Collection Ids",
            "type": "array"
          },
          "freeze_sources": {
            "default": true,
            "description": "drain: make the sources read-only while it runs, so new uploads don't keep landing on them, and put them back afterwards.",
            "title": "Freeze Sources",
            "type": "boolean"
          },
          "kind": {
            "description": "drain: move everything off the `sources` volumes. consolidate: move the files of the `collection_ids` collections.",
            "title": "Kind",
            "type": "string"
          },
          "sources": {
            "description": "drain: the volumes to empty.",
            "items": {
              "type": "string"
            },
            "title": "Sources",
            "type": "array"
          },
          "targets": {
            "description": "Volumes to put the files on, in order of preference: a file goes to the first that is usable and has room.",
            "items": {
              "type": "string"
            },
            "title": "Targets",
            "type": "array"
          },
          "verify": {
            "default": "copy",
            "description": "copy: each file is hashed as it is copied and must match its recorded hash. full: the copy is also read back and hashed (about twice the reading).",
            "title": "Verify",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "targets"
        ],
        "title": "TransferRequest",
        "type": "object"
      },
      "TransferResponse": {
        "properties": {
          "auto_resume": {
            "description": "Paused only because a volume stopped answering, and will carry on by itself when it does.",
            "title": "Auto Resume",
            "type": "boolean"
          },
          "control": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A pause or cancel asked for and not yet acted on.",
            "title": "Control"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "failures": {
            "description": "Files that couldn't be moved (the first few hundred).",
            "items": {
              "$ref": "#/components/schemas/TransferFailureResponse"
            },
            "title": "Failures",
            "type": "array"
          },
          "failures_total": {
            "title": "Failures Total",
            "type": "integer"
          },
          "finished_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finished At"
          },
          "frozen": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Volumes made read-only for the duration, and what each was before.",
            "title": "Frozen",
            "type": "object"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          },
          "live": {
            "description": "Running on a thread of this server right now.",
            "title": "Live",
            "type": "boolean"
          },
          "pause_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pause Reason"
          },
          "plan": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TransferPlanResponse"
              },
              {
                "type": "null"
              }
            ]
          },
          "progress": {
            "$ref": "#/components/schemas/TransferProgressResponse"
          },
          "spec": {
            "$ref": "#/components/schemas/TransferRequest"
          },
          "started_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Started At"
          },
          "status": {
            "description": "running, paused, completed, failed, cancelled or interrupted (the process died; resumable).",
            "title": "Status",
            "type": "string"
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At"
          }
        },
        "required": [
          "id",
          "kind",
          "status",
          "spec",
          "plan",
          "progress",
          "failures",
          "failures_total",
          "pause_reason",
          "auto_resume",
          "error",
          "control",
          "frozen",
          "live",
          "created_at",
          "started_at",
          "finished_at",
          "updated_at"
        ],
        "title": "TransferResponse",
        "type": "object"
      },
      "TriggerBreakdownPointResponse": {
        "properties": {
          "count": {
            "title": "Count",
            "type": "integer"
          },
          "trigger": {
            "description": "One of: record_created, record_updated, manual.",
            "title": "Trigger",
            "type": "string"
          }
        },
        "required": [
          "trigger",
          "count"
        ],
        "title": "TriggerBreakdownPointResponse",
        "type": "object"
      },
      "TriggerBreakdownResponse": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/TriggerBreakdownPointResponse"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "TriggerBreakdownResponse",
        "type": "object"
      },
      "UISettingsResponse": {
        "properties": {
          "show_advanced": {
            "title": "Show Advanced",
            "type": "boolean"
          }
        },
        "required": [
          "show_advanced"
        ],
        "title": "UISettingsResponse",
        "type": "object"
      },
      "UpdateAttempt": {
        "properties": {
          "at": {
            "description": "When it finished (UTC, `YYYY-MM-DDTHH:MM:SSZ`).",
            "title": "At",
            "type": "string"
          },
          "from_version": {
            "description": "The version it updated from.",
            "title": "From Version",
            "type": "string"
          },
          "message": {
            "description": "What went wrong; blank when it worked.",
            "title": "Message",
            "type": "string"
          },
          "ok": {
            "description": "Whether a newer version was installed.",
            "title": "Ok",
            "type": "boolean"
          },
          "to_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The version installed afterwards.",
            "title": "To Version"
          }
        },
        "required": [
          "at",
          "from_version",
          "to_version",
          "ok",
          "message"
        ],
        "title": "UpdateAttempt",
        "type": "object"
      },
      "UpdateDatasetRequest": {
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "rename": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rename"
          },
          "schemas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replace the collection's schema list. Omit or null to leave unchanged. A schema with records in the collection can't be removed.",
            "title": "Schemas"
          },
          "scope": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "'local' or 'global'. Omit or null to leave unchanged. A global collection that other collections reference can't become local.",
            "title": "Scope"
          },
          "timezone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "IANA timezone for datetime values in this collection. Omit or null to leave unchanged; an empty string clears it back to unset.",
            "title": "Timezone"
          }
        },
        "title": "UpdateDatasetRequest",
        "type": "object"
      },
      "UpdateExportDefinitionRequest": {
        "properties": {
          "fields": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replace the file fields; omit to leave as is.",
            "title": "Fields"
          },
          "files_layout": {
            "anyOf": [
              {
                "enum": [
                  "tree",
                  "grouped",
                  "flat"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Change the layout; omit to leave as is.",
            "title": "Files Layout"
          },
          "filter_tree": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replace the filter; send null to clear it.",
            "title": "Filter Tree"
          },
          "holder": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Change the kind; send null for 'any beneath'.",
            "title": "Holder"
          },
          "include_files": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Take the files or not; omit to leave as is.",
            "title": "Include Files"
          },
          "rename": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "New name.",
            "title": "Rename"
          },
          "tables": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TableRequest"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replace the tables; send an empty list to remove them.",
            "title": "Tables"
          }
        },
        "title": "UpdateExportDefinitionRequest",
        "type": "object"
      },
      "UpdateFieldRequest": {
        "properties": {
          "default": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Default"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "New display name. Send an empty string to clear it and fall back to the derived label; omit the key to leave it unchanged.",
            "title": "Label"
          },
          "rename": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rename"
          },
          "required": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Required"
          },
          "restrictions": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Restrictions"
          }
        },
        "title": "UpdateFieldRequest",
        "type": "object"
      },
      "UpdateIdentityRequest": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "maxLength": 100,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The name to record on changes made in this project; blank or null goes back to the default (the operating-system user). Saved in the project's config.toml.",
            "title": "Name"
          }
        },
        "title": "UpdateIdentityRequest",
        "type": "object"
      },
      "UpdateMapSettingsRequest": {
        "properties": {
          "attribution": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Plain-text credit for the provider, or null.",
            "title": "Attribution"
          },
          "tile_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "XYZ tile URL (http or https, with {z}, {x}, {y}), or null to clear.",
            "title": "Tile Url"
          }
        },
        "required": [
          "tile_url"
        ],
        "title": "UpdateMapSettingsRequest",
        "type": "object"
      },
      "UpdateRecordRequest": {
        "properties": {
          "data": {
            "additionalProperties": true,
            "title": "Data",
            "type": "object"
          }
        },
        "required": [
          "data"
        ],
        "title": "UpdateRecordRequest",
        "type": "object"
      },
      "UpdateRetentionSettingsRequest": {
        "description": "Only the fields sent are changed; send null for `audit_days` or\n`run_days` to keep that kind forever.",
        "properties": {
          "audit_days": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Audit Days"
          },
          "auto_purge_deleted": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Auto Purge Deleted"
          },
          "purge_after_days": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Purge After Days"
          },
          "run_days": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Run Days"
          }
        },
        "title": "UpdateRetentionSettingsRequest",
        "type": "object"
      },
      "UpdateSchemaRequest": {
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "display_template": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Template that names the schema's records. Send an empty string to clear it; omit the key to leave it unchanged.",
            "title": "Display Template"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "New display name. Send an empty string to clear it and fall back to the derived label; omit the key to leave it unchanged.",
            "title": "Label"
          },
          "rename": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rename"
          }
        },
        "title": "UpdateSchemaRequest",
        "type": "object"
      },
      "UpdateStatusResponse": {
        "properties": {
          "blocked": {
            "description": "Why it can't, in plain words; blank when it can.",
            "title": "Blocked",
            "type": "string"
          },
          "can_update": {
            "description": "Whether the app can update this copy.",
            "title": "Can Update",
            "type": "boolean"
          },
          "current": {
            "description": "The version running now.",
            "title": "Current",
            "type": "string"
          },
          "error": {
            "description": "Why PyPI couldn't be asked; blank when it was.",
            "title": "Error",
            "type": "string"
          },
          "installer": {
            "description": "How this copy was installed: desktop, frozen, editable, pipx, uv or pip.",
            "title": "Installer",
            "type": "string"
          },
          "last": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UpdateAttempt"
              },
              {
                "type": "null"
              }
            ],
            "description": "The outcome of the last update started from the app."
          },
          "latest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The newest version on PyPI (pre-releases too when asked for); null when PyPI couldn't be reached.",
            "title": "Latest"
          },
          "newer": {
            "description": "Whether `latest` is newer than `current`.",
            "title": "Newer",
            "type": "boolean"
          },
          "pre": {
            "description": "Whether pre-releases were looked for.",
            "title": "Pre",
            "type": "boolean"
          }
        },
        "required": [
          "current",
          "latest",
          "newer",
          "pre",
          "installer",
          "can_update",
          "blocked",
          "error",
          "last"
        ],
        "title": "UpdateStatusResponse",
        "type": "object"
      },
      "UpdateUISettingsRequest": {
        "properties": {
          "show_advanced": {
            "title": "Show Advanced",
            "type": "boolean"
          }
        },
        "required": [
          "show_advanced"
        ],
        "title": "UpdateUISettingsRequest",
        "type": "object"
      },
      "UpdateViewRequest": {
        "properties": {
          "columns": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replace the column list; omit the key to leave it unchanged.",
            "title": "Columns"
          },
          "files_layout": {
            "anyOf": [
              {
                "enum": [
                  "tree",
                  "grouped",
                  "flat"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Change how the view's files are arranged when exported; omit the key to leave it unchanged.",
            "title": "Files Layout"
          },
          "filter_tree": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replace the filter tree; send null to clear it, omit the key to leave it unchanged.",
            "title": "Filter Tree"
          },
          "rename": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "New name; same rules as when creating.",
            "title": "Rename"
          },
          "sort": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replace the sort order; omit the key to leave it unchanged.",
            "title": "Sort"
          }
        },
        "title": "UpdateViewRequest",
        "type": "object"
      },
      "UpdateVolumeRequest": {
        "properties": {
          "allocated_gb": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allocated Gb"
          },
          "clear_allocation": {
            "default": false,
            "title": "Clear Allocation",
            "type": "boolean"
          },
          "path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Path"
          },
          "state": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "active, readonly (readable, never written to) or retired.",
            "title": "State"
          }
        },
        "title": "UpdateVolumeRequest",
        "type": "object"
      },
      "UploadResult": {
        "properties": {
          "filename": {
            "title": "Filename",
            "type": "string"
          },
          "plugin_id": {
            "title": "Plugin Id",
            "type": "string"
          }
        },
        "required": [
          "filename",
          "plugin_id"
        ],
        "title": "UploadResult",
        "type": "object"
      },
      "UsageTotalsResponse": {
        "properties": {
          "input_tokens": {
            "title": "Input Tokens",
            "type": "integer"
          },
          "output_tokens": {
            "title": "Output Tokens",
            "type": "integer"
          },
          "requests": {
            "title": "Requests",
            "type": "integer"
          },
          "total_tokens": {
            "title": "Total Tokens",
            "type": "integer"
          }
        },
        "required": [
          "requests",
          "input_tokens",
          "output_tokens",
          "total_tokens"
        ],
        "title": "UsageTotalsResponse",
        "type": "object"
      },
      "UserMessage": {
        "properties": {
          "content": {
            "title": "Content",
            "type": "string"
          },
          "role": {
            "const": "user",
            "default": "user",
            "title": "Role",
            "type": "string"
          }
        },
        "required": [
          "content"
        ],
        "title": "UserMessage",
        "type": "object"
      },
      "ValidationError": {
        "properties": {
          "ctx": {
            "title": "Context",
            "type": "object"
          },
          "input": {
            "title": "Input"
          },
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "title": "Location",
            "type": "array"
          },
          "msg": {
            "title": "Message",
            "type": "string"
          },
          "type": {
            "title": "Error Type",
            "type": "string"
          }
        },
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError",
        "type": "object"
      },
      "ViewResponse": {
        "properties": {
          "columns": {
            "description": "Base schema field names to show, in order (own or inherited). May also include single-hop reference-field joins as 'ref_field.target_field' (e.g. 'customer.email').",
            "items": {
              "type": "string"
            },
            "title": "Columns",
            "type": "array"
          },
          "files_layout": {
            "default": "tree",
            "description": "How the view's files are arranged when exported as a folder or zip: 'tree' puts each file in a folder per record above it (Encounter/Recording/Selection/...), 'grouped' keeps the folders above the records that hold the files but gathers those records' files into one folder named for their kind (Encounter/Recording/Selections/...), 'flat' puts every file in one folder.",
            "enum": [
              "tree",
              "grouped",
              "flat"
            ],
            "title": "Files Layout",
            "type": "string"
          },
          "filter_tree": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "AND/OR filter tree, same shape as the records 'filter' query parameter (conditions may name an ancestor or descendant schema).",
            "title": "Filter Tree"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "schema_id": {
            "title": "Schema Id",
            "type": "string"
          },
          "schema_name": {
            "title": "Schema Name",
            "type": "string"
          },
          "sort": {
            "description": "Ordered list of {field, direction} entries; direction is 'asc' or 'desc'.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Sort",
            "type": "array"
          }
        },
        "required": [
          "id",
          "schema_id",
          "schema_name",
          "name",
          "columns",
          "sort"
        ],
        "title": "ViewResponse",
        "type": "object"
      },
      "VolumeStatsResponse": {
        "properties": {
          "allocated_gb": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allocated Gb"
          },
          "available": {
            "description": "True if the volume's files can be read right now (online, read-only or retired).",
            "title": "Available",
            "type": "boolean"
          },
          "civex_used_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Civex Used Bytes"
          },
          "disk_free_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disk Free Bytes"
          },
          "disk_total_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disk Total Bytes"
          },
          "fix": {
            "description": "A plain-language next step for an offline or wrong-drive volume; empty otherwise.",
            "title": "Fix",
            "type": "string"
          },
          "history_bytes": {
            "default": 0,
            "title": "History Bytes",
            "type": "integer"
          },
          "history_files": {
            "default": 0,
            "description": "Files kept only because a workflow run took them as an input.",
            "title": "History Files",
            "type": "integer"
          },
          "in_queue": {
            "title": "In Queue",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "network": {
            "default": false,
            "description": "The volume's folder is on a network drive.",
            "title": "Network",
            "type": "boolean"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "reason": {
            "description": "What civex expected versus what it found; empty when online.",
            "title": "Reason",
            "type": "string"
          },
          "state": {
            "description": "online, offline (path not there, e.g. drive unplugged), wrong_drive (something else is mounted there), readonly or retired.",
            "title": "State",
            "type": "string"
          },
          "unused_bytes": {
            "default": 0,
            "title": "Unused Bytes",
            "type": "integer"
          },
          "unused_files": {
            "default": 0,
            "description": "Files on the volume that nothing uses; garbage collection can reclaim them.",
            "title": "Unused Files",
            "type": "integer"
          },
          "warning": {
            "title": "Warning",
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "path",
          "allocated_gb",
          "civex_used_bytes",
          "disk_free_bytes",
          "disk_total_bytes",
          "available",
          "state",
          "reason",
          "fix",
          "warning",
          "in_queue"
        ],
        "title": "VolumeStatsResponse",
        "type": "object"
      },
      "WorkflowDetailResponse": {
        "properties": {
          "content": {
            "title": "Content",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "filename": {
            "title": "Filename",
            "type": "string"
          },
          "inputs": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/WorkflowInputResponse"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Inputs"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "record_schema": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Record Schema"
          },
          "stem": {
            "title": "Stem",
            "type": "string"
          },
          "step_list": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/WorkflowStepResponse"
            },
            "title": "Step List",
            "type": "array"
          },
          "steps": {
            "title": "Steps",
            "type": "integer"
          },
          "triggers": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/WorkflowTriggerResponse"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Triggers"
          }
        },
        "required": [
          "name",
          "description",
          "steps",
          "filename",
          "stem",
          "content"
        ],
        "title": "WorkflowDetailResponse",
        "type": "object"
      },
      "WorkflowInputResponse": {
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "type": {
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "type",
          "label",
          "description"
        ],
        "title": "WorkflowInputResponse",
        "type": "object"
      },
      "WorkflowJobResponse": {
        "properties": {
          "affected_records": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Affected Records"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "depth": {
            "default": 0,
            "description": "How many workflow-triggered-by-workflow hops deep this run is: 0 for a run started by a person or an ordinary edit, 1 for a run started by another run's save, and so on.",
            "title": "Depth",
            "type": "integer"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "error_details": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error Details"
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finished At"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "log": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Log"
          },
          "record_id": {
            "title": "Record Id",
            "type": "string"
          },
          "schema_name": {
            "title": "Schema Name",
            "type": "string"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Started At"
          },
          "status": {
            "title": "Status",
            "type": "string"
          },
          "step_executions": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Step Executions"
          },
          "trigger": {
            "title": "Trigger",
            "type": "string"
          },
          "trigger_detail": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "What caused the run. `changes` lists each field that changed, with a short `before` and `after` and whether the workflow was `watched` for it. `caused_by` is {job_id, workflow} when another run's own save started this one, else null. Null for a run started by hand.",
            "title": "Trigger Detail"
          },
          "workflow_name": {
            "title": "Workflow Name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "workflow_name",
          "record_id",
          "schema_name",
          "trigger",
          "status",
          "error",
          "error_details",
          "log",
          "step_executions",
          "affected_records",
          "created_at",
          "started_at",
          "finished_at"
        ],
        "title": "WorkflowJobResponse",
        "type": "object"
      },
      "WorkflowResponse": {
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "filename": {
            "title": "Filename",
            "type": "string"
          },
          "inputs": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/WorkflowInputResponse"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Inputs"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "record_schema": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Record Schema"
          },
          "runs_on": {
            "description": "What starts it by itself, one line each (\"record_created on sample (site)\"); empty if only run by hand.",
            "items": {
              "type": "string"
            },
            "title": "Runs On",
            "type": "array"
          },
          "stem": {
            "title": "Stem",
            "type": "string"
          },
          "steps": {
            "title": "Steps",
            "type": "integer"
          }
        },
        "required": [
          "name",
          "description",
          "steps",
          "filename",
          "stem"
        ],
        "title": "WorkflowResponse",
        "type": "object"
      },
      "WorkflowSaveRequest": {
        "properties": {
          "content": {
            "title": "Content",
            "type": "string"
          }
        },
        "required": [
          "content"
        ],
        "title": "WorkflowSaveRequest",
        "type": "object"
      },
      "WorkflowStepResponse": {
        "properties": {
          "condition": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Condition"
          },
          "config": {
            "additionalProperties": true,
            "title": "Config",
            "type": "object"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "inputs": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Inputs",
            "type": "object"
          },
          "plugin": {
            "title": "Plugin",
            "type": "string"
          }
        },
        "required": [
          "id",
          "plugin",
          "config",
          "inputs"
        ],
        "title": "WorkflowStepResponse",
        "type": "object"
      },
      "WorkflowTriggerResponse": {
        "properties": {
          "fields": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fields"
          },
          "schema_name": {
            "title": "Schema Name",
            "type": "string"
          }
        },
        "required": [
          "schema_name"
        ],
        "title": "WorkflowTriggerResponse",
        "type": "object"
      },
      "civex__server__routers__remote__LibraryPublishRequest": {
        "properties": {
          "kind": {
            "description": "workflow or plugin.",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "description": "The workflow's or plugin file's name here.",
            "title": "Name",
            "type": "string"
          },
          "with_plugins": {
            "default": true,
            "description": "A workflow: send the plugins its steps use too.",
            "title": "With Plugins",
            "type": "boolean"
          }
        },
        "required": [
          "kind",
          "name"
        ],
        "title": "LibraryPublishRequest",
        "type": "object"
      },
      "civex__server__routers__remote__LibraryPublishResponse": {
        "properties": {
          "items": {
            "description": "The versions stored.",
            "items": {
              "$ref": "#/components/schemas/LibraryItemResponse"
            },
            "title": "Items",
            "type": "array"
          },
          "warnings": {
            "description": "Shared workflows still on an older version of a plugin that the new version would break.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "LibraryPublishResponse",
        "type": "object"
      },
      "civex__server__routers__sync_peer__LibraryPublishRequest": {
        "properties": {
          "items": {
            "description": "A workflow and the plugins it uses, or a plugin. Taken whole or not at all; new text becomes the next version.",
            "items": {
              "$ref": "#/components/schemas/LibraryItemBody"
            },
            "maxItems": 50,
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "LibraryPublishRequest",
        "type": "object"
      },
      "civex__server__routers__sync_peer__LibraryPublishResponse": {
        "properties": {
          "items": {
            "description": "The newest version of each item, without its text: kind, name, sha256, size, version, title, description, provides, needs, triggers, pins, contract, published_by, published_at, and its history (every version).",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Items",
            "type": "array"
          },
          "warnings": {
            "description": "What to know: shared workflows still on an older version of a plugin that the new version would break.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "LibraryPublishResponse",
        "type": "object"
      }
    }
  },
  "info": {
    "contact": {
      "email": "sullivanj041@gmail.com",
      "name": "James Sullivan"
    },
    "description": "civex is a local-first research data management system: schemas, records, files, and workflow automation in one place, running on your own machine against your own database.\n\nEvery endpoint below is served under the `/api` prefix (e.g. `GET /api/schemas`); paths in this reference omit that prefix for brevity.\n\n## Errors\n\nErrors share one envelope shape across the API. Domain errors (not found, already exists, validation, misconfiguration) return a 4xx/5xx status with a JSON body of `{\"detail\": \"<message>\"}`. Request body/query validation failures return 422 with `{\"detail\": \"Request validation failed\", \"errors\": [...]}`, one entry per invalid field. Anything unexpected returns a generic 500 with `{\"detail\": \"Internal server error\", \"request_id\": \"<id>\"}` \u2014 the same id echoed on the `x-request-id` response header, for correlating with server logs.\n\nSee the [getting started guide](https://civexdata.github.io/civex-docs/getting-started/install.html) for installing the CLI and standing up your first project.\n",
    "license": {
      "name": "PolyForm Shield 1.0.0",
      "url": "https://polyformproject.org/licenses/shield/1.0.0"
    },
    "title": "civex",
    "version": "2.0.0rc5.post2"
  },
  "openapi": "3.1.0",
  "paths": {
    "/api/ai/chat": {
      "post": {
        "operationId": "chat_api_ai_chat_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Chat",
        "tags": [
          "ai"
        ]
      }
    },
    "/api/ai/config": {
      "get": {
        "operationId": "get_ai_config_api_ai_config_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiConfigResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Ai Config",
        "tags": [
          "ai"
        ]
      },
      "patch": {
        "operationId": "update_ai_config_api_ai_config_patch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AiConfigUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiConfigResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Ai Config",
        "tags": [
          "ai"
        ]
      }
    },
    "/api/ai/ollama/models": {
      "get": {
        "description": "List models installed in a running Ollama instance.",
        "operationId": "ollama_models_api_ai_ollama_models_get",
        "parameters": [
          {
            "in": "query",
            "name": "base_url",
            "required": false,
            "schema": {
              "default": "http://localhost:11434/v1",
              "title": "Base Url",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Ollama Models",
        "tags": [
          "ai"
        ]
      }
    },
    "/api/ai/openrouter/auth-url": {
      "get": {
        "description": "Return the OAuth URL for the OpenRouter login flow.",
        "operationId": "openrouter_auth_url_api_ai_openrouter_auth_url_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Openrouter Auth Url",
        "tags": [
          "ai"
        ]
      }
    },
    "/api/ai/openrouter/callback": {
      "get": {
        "description": "Receive OAuth code from OpenRouter, exchange for key, save to config.",
        "operationId": "openrouter_callback_api_ai_openrouter_callback_get",
        "parameters": [
          {
            "in": "query",
            "name": "code",
            "required": true,
            "schema": {
              "title": "Code",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Openrouter Callback",
        "tags": [
          "ai"
        ]
      }
    },
    "/api/ai/openrouter/limits": {
      "get": {
        "description": "Proxy GET https://openrouter.ai/api/v1/key to expose usage/rate-limit info.",
        "operationId": "openrouter_limits_api_ai_openrouter_limits_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Openrouter Limits",
        "tags": [
          "ai"
        ]
      }
    },
    "/api/ai/usage": {
      "get": {
        "description": "All-time token usage, regardless of provider/model -- backs both the\nAI panel's usage display and `civex ai usage`.",
        "operationId": "get_ai_usage_api_ai_usage_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiUsageResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Ai Usage",
        "tags": [
          "ai"
        ]
      }
    },
    "/api/analytics/ai/usage": {
      "get": {
        "description": "AI provider token usage over time, broken out by provider and model.\nApplies `start`, `end`, `bucket`, plus this endpoint's own `provider`\nand `model` params -- not part of the shared filter contract since no\nother endpoint has a use for them.",
        "operationId": "ai_token_usage_api_analytics_ai_usage_get",
        "parameters": [
          {
            "description": "AI provider to scope to, e.g. 'anthropic'.",
            "in": "query",
            "name": "provider",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "AI provider to scope to, e.g. 'anthropic'.",
              "title": "Provider"
            }
          },
          {
            "description": "AI model to scope to, e.g. 'claude-sonnet-5'.",
            "in": "query",
            "name": "model",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "AI model to scope to, e.g. 'claude-sonnet-5'.",
              "title": "Model"
            }
          },
          {
            "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
              "title": "Start"
            }
          },
          {
            "description": "Exclusive upper bound (UTC).",
            "in": "query",
            "name": "end",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exclusive upper bound (UTC).",
              "title": "End"
            }
          },
          {
            "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
            "in": "query",
            "name": "bucket",
            "required": false,
            "schema": {
              "default": "day",
              "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "title": "Bucket",
              "type": "string"
            }
          },
          {
            "description": "Dataset name to scope to.",
            "in": "query",
            "name": "dataset",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Dataset name to scope to.",
              "title": "Dataset"
            }
          },
          {
            "description": "Schema name to scope to.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Schema name to scope to.",
              "title": "Schema"
            }
          },
          {
            "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
            "in": "query",
            "name": "workflow_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
              "title": "Workflow Id"
            }
          },
          {
            "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
            "in": "query",
            "name": "plugin_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
              "title": "Plugin Id"
            }
          },
          {
            "description": "Job or step status to scope to.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Job or step status to scope to.",
              "title": "Status"
            }
          },
          {
            "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
              "title": "Trigger"
            }
          },
          {
            "description": "Audit entity type to scope to: record, schema, field, or dataset.",
            "in": "query",
            "name": "entity_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit entity type to scope to: record, schema, field, or dataset.",
              "title": "Entity Type"
            }
          },
          {
            "description": "Audit action to scope to: create, update, delete, or purge.",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit action to scope to: create, update, delete, or purge.",
              "title": "Action"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AiTokenUsageResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Ai Token Usage",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/audit/events": {
      "get": {
        "description": "Audit log entry counts over time, broken out by action and\nentity_type. Applies `start`, `end`, `bucket`, `entity_type`, `action`.\n`AuditLog` carries no actor/user field, so this endpoint has no\nper-user breakdown.",
        "operationId": "audit_event_counts_api_analytics_audit_events_get",
        "parameters": [
          {
            "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
              "title": "Start"
            }
          },
          {
            "description": "Exclusive upper bound (UTC).",
            "in": "query",
            "name": "end",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exclusive upper bound (UTC).",
              "title": "End"
            }
          },
          {
            "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
            "in": "query",
            "name": "bucket",
            "required": false,
            "schema": {
              "default": "day",
              "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "title": "Bucket",
              "type": "string"
            }
          },
          {
            "description": "Dataset name to scope to.",
            "in": "query",
            "name": "dataset",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Dataset name to scope to.",
              "title": "Dataset"
            }
          },
          {
            "description": "Schema name to scope to.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Schema name to scope to.",
              "title": "Schema"
            }
          },
          {
            "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
            "in": "query",
            "name": "workflow_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
              "title": "Workflow Id"
            }
          },
          {
            "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
            "in": "query",
            "name": "plugin_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
              "title": "Plugin Id"
            }
          },
          {
            "description": "Job or step status to scope to.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Job or step status to scope to.",
              "title": "Status"
            }
          },
          {
            "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
              "title": "Trigger"
            }
          },
          {
            "description": "Audit entity type to scope to: record, schema, field, or dataset.",
            "in": "query",
            "name": "entity_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit entity type to scope to: record, schema, field, or dataset.",
              "title": "Entity Type"
            }
          },
          {
            "description": "Audit action to scope to: create, update, delete, or purge.",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit action to scope to: create, update, delete, or purge.",
              "title": "Action"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditEventCountsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Audit Event Counts",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/jobs/by-trigger": {
      "get": {
        "description": "Job counts grouped by trigger type (record_created, record_updated,\nmanual) -- a snapshot over the filtered range, not a time series.\nApplies `start`, `end`, `workflow_id`, `status`, `trigger`.",
        "operationId": "job_trigger_breakdown_api_analytics_jobs_by_trigger_get",
        "parameters": [
          {
            "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
              "title": "Start"
            }
          },
          {
            "description": "Exclusive upper bound (UTC).",
            "in": "query",
            "name": "end",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exclusive upper bound (UTC).",
              "title": "End"
            }
          },
          {
            "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
            "in": "query",
            "name": "bucket",
            "required": false,
            "schema": {
              "default": "day",
              "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "title": "Bucket",
              "type": "string"
            }
          },
          {
            "description": "Dataset name to scope to.",
            "in": "query",
            "name": "dataset",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Dataset name to scope to.",
              "title": "Dataset"
            }
          },
          {
            "description": "Schema name to scope to.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Schema name to scope to.",
              "title": "Schema"
            }
          },
          {
            "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
            "in": "query",
            "name": "workflow_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
              "title": "Workflow Id"
            }
          },
          {
            "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
            "in": "query",
            "name": "plugin_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
              "title": "Plugin Id"
            }
          },
          {
            "description": "Job or step status to scope to.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Job or step status to scope to.",
              "title": "Status"
            }
          },
          {
            "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
              "title": "Trigger"
            }
          },
          {
            "description": "Audit entity type to scope to: record, schema, field, or dataset.",
            "in": "query",
            "name": "entity_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit entity type to scope to: record, schema, field, or dataset.",
              "title": "Entity Type"
            }
          },
          {
            "description": "Audit action to scope to: create, update, delete, or purge.",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit action to scope to: create, update, delete, or purge.",
              "title": "Action"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TriggerBreakdownResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Job Trigger Breakdown",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/jobs/duration": {
      "get": {
        "description": "Step execution duration distribution: summary stats (count, avg,\nmin, max, p50, p90, p99, in seconds), a histogram of counts by\nduration bucket, and which bucket each percentile falls in. Applies\n`start`, `end`, `plugin_id`, `status` (matched against the step's own\nstatus, not the parent job's).",
        "operationId": "job_duration_stats_api_analytics_jobs_duration_get",
        "parameters": [
          {
            "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
              "title": "Start"
            }
          },
          {
            "description": "Exclusive upper bound (UTC).",
            "in": "query",
            "name": "end",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exclusive upper bound (UTC).",
              "title": "End"
            }
          },
          {
            "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
            "in": "query",
            "name": "bucket",
            "required": false,
            "schema": {
              "default": "day",
              "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "title": "Bucket",
              "type": "string"
            }
          },
          {
            "description": "Dataset name to scope to.",
            "in": "query",
            "name": "dataset",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Dataset name to scope to.",
              "title": "Dataset"
            }
          },
          {
            "description": "Schema name to scope to.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Schema name to scope to.",
              "title": "Schema"
            }
          },
          {
            "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
            "in": "query",
            "name": "workflow_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
              "title": "Workflow Id"
            }
          },
          {
            "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
            "in": "query",
            "name": "plugin_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
              "title": "Plugin Id"
            }
          },
          {
            "description": "Job or step status to scope to.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Job or step status to scope to.",
              "title": "Status"
            }
          },
          {
            "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
              "title": "Trigger"
            }
          },
          {
            "description": "Audit entity type to scope to: record, schema, field, or dataset.",
            "in": "query",
            "name": "entity_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit entity type to scope to: record, schema, field, or dataset.",
              "title": "Entity Type"
            }
          },
          {
            "description": "Audit action to scope to: create, update, delete, or purge.",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit action to scope to: create, update, delete, or purge.",
              "title": "Action"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobDurationStatsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Job Duration Stats",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/jobs/failures-by-plugin": {
      "get": {
        "description": "Failed step-execution counts over time, broken out by plugin --\ngeneralizes the aggregate `civex worker stats` uses with a date range\nand bucket size. Applies `start`, `end`, `bucket`, `plugin_id`.",
        "operationId": "plugin_failure_counts_api_analytics_jobs_failures_by_plugin_get",
        "parameters": [
          {
            "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
              "title": "Start"
            }
          },
          {
            "description": "Exclusive upper bound (UTC).",
            "in": "query",
            "name": "end",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exclusive upper bound (UTC).",
              "title": "End"
            }
          },
          {
            "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
            "in": "query",
            "name": "bucket",
            "required": false,
            "schema": {
              "default": "day",
              "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "title": "Bucket",
              "type": "string"
            }
          },
          {
            "description": "Dataset name to scope to.",
            "in": "query",
            "name": "dataset",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Dataset name to scope to.",
              "title": "Dataset"
            }
          },
          {
            "description": "Schema name to scope to.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Schema name to scope to.",
              "title": "Schema"
            }
          },
          {
            "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
            "in": "query",
            "name": "workflow_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
              "title": "Workflow Id"
            }
          },
          {
            "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
            "in": "query",
            "name": "plugin_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
              "title": "Plugin Id"
            }
          },
          {
            "description": "Job or step status to scope to.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Job or step status to scope to.",
              "title": "Status"
            }
          },
          {
            "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
              "title": "Trigger"
            }
          },
          {
            "description": "Audit entity type to scope to: record, schema, field, or dataset.",
            "in": "query",
            "name": "entity_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit entity type to scope to: record, schema, field, or dataset.",
              "title": "Entity Type"
            }
          },
          {
            "description": "Audit action to scope to: create, update, delete, or purge.",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit action to scope to: create, update, delete, or purge.",
              "title": "Action"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginFailureCountsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Plugin Failure Counts",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/jobs/status": {
      "get": {
        "description": "Workflow job counts over time, broken out by status. Applies `start`,\n`end`, `bucket`, `workflow_id`, `trigger`, `status`.",
        "operationId": "job_status_counts_api_analytics_jobs_status_get",
        "parameters": [
          {
            "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
              "title": "Start"
            }
          },
          {
            "description": "Exclusive upper bound (UTC).",
            "in": "query",
            "name": "end",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exclusive upper bound (UTC).",
              "title": "End"
            }
          },
          {
            "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
            "in": "query",
            "name": "bucket",
            "required": false,
            "schema": {
              "default": "day",
              "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "title": "Bucket",
              "type": "string"
            }
          },
          {
            "description": "Dataset name to scope to.",
            "in": "query",
            "name": "dataset",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Dataset name to scope to.",
              "title": "Dataset"
            }
          },
          {
            "description": "Schema name to scope to.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Schema name to scope to.",
              "title": "Schema"
            }
          },
          {
            "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
            "in": "query",
            "name": "workflow_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
              "title": "Workflow Id"
            }
          },
          {
            "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
            "in": "query",
            "name": "plugin_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
              "title": "Plugin Id"
            }
          },
          {
            "description": "Job or step status to scope to.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Job or step status to scope to.",
              "title": "Status"
            }
          },
          {
            "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
              "title": "Trigger"
            }
          },
          {
            "description": "Audit entity type to scope to: record, schema, field, or dataset.",
            "in": "query",
            "name": "entity_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit entity type to scope to: record, schema, field, or dataset.",
              "title": "Entity Type"
            }
          },
          {
            "description": "Audit action to scope to: create, update, delete, or purge.",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit action to scope to: create, update, delete, or purge.",
              "title": "Action"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatusCountsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Job Status Counts",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/records/counts": {
      "get": {
        "description": "Current record totals by dataset and schema -- a snapshot, not a time\nseries. Applies the `dataset` and `schema` filters; the rest of the\nshared filter contract is ignored here.",
        "operationId": "record_counts_api_analytics_records_counts_get",
        "parameters": [
          {
            "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
              "title": "Start"
            }
          },
          {
            "description": "Exclusive upper bound (UTC).",
            "in": "query",
            "name": "end",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exclusive upper bound (UTC).",
              "title": "End"
            }
          },
          {
            "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
            "in": "query",
            "name": "bucket",
            "required": false,
            "schema": {
              "default": "day",
              "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "title": "Bucket",
              "type": "string"
            }
          },
          {
            "description": "Dataset name to scope to.",
            "in": "query",
            "name": "dataset",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Dataset name to scope to.",
              "title": "Dataset"
            }
          },
          {
            "description": "Schema name to scope to.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Schema name to scope to.",
              "title": "Schema"
            }
          },
          {
            "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
            "in": "query",
            "name": "workflow_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
              "title": "Workflow Id"
            }
          },
          {
            "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
            "in": "query",
            "name": "plugin_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
              "title": "Plugin Id"
            }
          },
          {
            "description": "Job or step status to scope to.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Job or step status to scope to.",
              "title": "Status"
            }
          },
          {
            "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
              "title": "Trigger"
            }
          },
          {
            "description": "Audit entity type to scope to: record, schema, field, or dataset.",
            "in": "query",
            "name": "entity_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit entity type to scope to: record, schema, field, or dataset.",
              "title": "Entity Type"
            }
          },
          {
            "description": "Audit action to scope to: create, update, delete, or purge.",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit action to scope to: create, update, delete, or purge.",
              "title": "Action"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordCountsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Record Counts",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/records/growth": {
      "get": {
        "description": "Record creation counts over time, broken out by dataset and schema.\nApplies `start`, `end`, `bucket`, `dataset`, `schema`.",
        "operationId": "record_growth_api_analytics_records_growth_get",
        "parameters": [
          {
            "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Inclusive lower bound (UTC) on the endpoint's primary timestamp column.",
              "title": "Start"
            }
          },
          {
            "description": "Exclusive upper bound (UTC).",
            "in": "query",
            "name": "end",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Exclusive upper bound (UTC).",
              "title": "End"
            }
          },
          {
            "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
            "in": "query",
            "name": "bucket",
            "required": false,
            "schema": {
              "default": "day",
              "description": "Time-bucket size for time-series endpoints. Ignored by current-state endpoints (e.g. record counts).",
              "enum": [
                "day",
                "week",
                "month"
              ],
              "title": "Bucket",
              "type": "string"
            }
          },
          {
            "description": "Dataset name to scope to.",
            "in": "query",
            "name": "dataset",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Dataset name to scope to.",
              "title": "Dataset"
            }
          },
          {
            "description": "Schema name to scope to.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Schema name to scope to.",
              "title": "Schema"
            }
          },
          {
            "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
            "in": "query",
            "name": "workflow_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow name to scope to -- workflows are identified by name, not a separate id.",
              "title": "Workflow Id"
            }
          },
          {
            "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
            "in": "query",
            "name": "plugin_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Plugin id to scope to, e.g. 'civex.load_file'.",
              "title": "Plugin Id"
            }
          },
          {
            "description": "Job or step status to scope to.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Job or step status to scope to.",
              "title": "Status"
            }
          },
          {
            "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Workflow trigger to scope to: record_created, record_updated, or manual.",
              "title": "Trigger"
            }
          },
          {
            "description": "Audit entity type to scope to: record, schema, field, or dataset.",
            "in": "query",
            "name": "entity_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit entity type to scope to: record, schema, field, or dataset.",
              "title": "Entity Type"
            }
          },
          {
            "description": "Audit action to scope to: create, update, delete, or purge.",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Audit action to scope to: create, update, delete, or purge.",
              "title": "Action"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordGrowthResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Record Growth",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/audit": {
      "get": {
        "description": "General-purpose audit search, filterable by entity type and/or id.\nPrefer `/records/{id}/audit` or `/schemas/{name}/audit` when scoping to a\nsingle known resource \u2014 this endpoint is for cross-entity queries.",
        "operationId": "list_audit_api_audit_get",
        "parameters": [
          {
            "description": "Filter to one entity type: record, schema, field, dataset, view.",
            "in": "query",
            "name": "entity_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter to one entity type: record, schema, field, dataset, view.",
              "title": "Entity Type"
            }
          },
          {
            "description": "Filter to a single entity's audit trail.",
            "in": "query",
            "name": "entity_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter to a single entity's audit trail.",
              "title": "Entity Id"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 1000,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "description": "Only entries of this action (create, update, ...).",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries of this action (create, update, ...).",
              "title": "Action"
            }
          },
          {
            "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
              "title": "Sort"
            }
          },
          {
            "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
              "title": "Since"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedAuditLogResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Audit",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/batches": {
      "post": {
        "description": "Start a batch for work done over many requests, such as an import. Send\nits id in an `X-Civex-Batch` header on each of them and what they change is\none event in history.",
        "operationId": "open_audit_batch_api_audit_batches_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenBatchRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditBatchResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Open Audit Batch",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/batches/{batch_id}": {
      "get": {
        "description": "One batch as an event, with everything in it counted by kind and action.",
        "operationId": "get_audit_batch_api_audit_batches__batch_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "batch_id",
            "required": true,
            "schema": {
              "title": "Batch Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditEventResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Audit Batch",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/batches/{batch_id}/entries": {
      "get": {
        "description": "The changes in one batch, with their field-level `changes`.",
        "operationId": "list_audit_batch_entries_api_audit_batches__batch_id__entries_get",
        "parameters": [
          {
            "in": "path",
            "name": "batch_id",
            "required": true,
            "schema": {
              "title": "Batch Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 1000,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "description": "Only entries of this action (create, update, ...).",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries of this action (create, update, ...).",
              "title": "Action"
            }
          },
          {
            "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
              "title": "Sort"
            }
          },
          {
            "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
              "title": "Since"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedAuditLogResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Audit Batch Entries",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/events": {
      "get": {
        "description": "The whole project's history as events, newest first. A batch (an import,\na delete that took a tree with it, a workflow run) is one event however\nmany changes it holds, with a count of what it did; any other change is an\nevent of its own, with its field-level `changes` and where the record is\n`now`. The filter and `q` match changes; an event is listed when any of its\nchanges match, with how many did.",
        "operationId": "list_audit_events_api_audit_events_get",
        "parameters": [
          {
            "description": "A filter tree as JSON (`{\"and\": [{\"field\": \"kind\", \"op\": \"eq\", \"value\": \"record\"}]}`), the same kind records and runs take. Fields come from GET /audit/filter-fields.",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A filter tree as JSON (`{\"and\": [{\"field\": \"kind\", \"op\": \"eq\", \"value\": \"record\"}]}`), the same kind records and runs take. Fields come from GET /audit/filter-fields.",
              "title": "Filter"
            }
          },
          {
            "description": "Text to find in what a change stored (a value, a file's name) or in a batch's label (a workflow's name, an imported file).",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text to find in what a change stored (a value, a file's name) or in a batch's label (a workflow's name, an imported file).",
              "title": "Q"
            }
          },
          {
            "description": "`timestamp:asc` for oldest first; newest first by default.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`timestamp:asc` for oldest first; newest first by default.",
              "title": "Sort"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedAuditEventsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Audit Events",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/filter-fields": {
      "get": {
        "description": "The fields a history filter may test, with their types and operators.",
        "operationId": "audit_filter_fields_api_audit_filter_fields_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/RunFieldResponse"
                  },
                  "title": "Response Audit Filter Fields Api Audit Filter Fields Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Audit Filter Fields",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/restore-all": {
      "get": {
        "description": "What restoring everything deleted that this filter matches would do,\nwithout doing it: how many collections, schemas, fields and records, how\nmany records come back in all, and how many are blocked because something\nabove them is deleted and not in the set.",
        "operationId": "plan_restore_all_api_audit_restore_all_get",
        "parameters": [
          {
            "description": "The history filter, as for `/audit/events`.",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The history filter, as for `/audit/events`.",
              "title": "Filter"
            }
          },
          {
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Q"
            }
          },
          {
            "description": "Only what this batch deleted: the id of a bulk delete's event in `/audit/events`, to undo it whole.",
            "in": "query",
            "name": "batch",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only what this batch deleted: the id of a bulk delete's event in `/audit/events`, to undo it whole.",
              "title": "Batch"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestoreAllPlanResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Plan Restore All",
        "tags": [
          "audit"
        ]
      },
      "post": {
        "description": "Restore everything deleted that the filter matches, as one event in\nhistory: collections and schemas first, then records parent-first. A record\nleft under something deleted that is not in the set stays deleted and is\ncounted as blocked.",
        "operationId": "restore_all_api_audit_restore_all_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestoreAllRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestoreAllResultResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore All",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/storage": {
      "get": {
        "description": "How history is stored: edits still to convert to what-changed form, how\nfar the background conversion has got, and the room a reclaim would give\nback.",
        "operationId": "history_storage_api_audit_storage_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HistoryStorageResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "History Storage",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/storage/reclaim": {
      "post": {
        "description": "Give unused room in the database file back to the disk (SQLite VACUUM).\nRefused while history is being converted. It needs about the file's size in\nfree disk while it runs, and the project waits for it.",
        "operationId": "reclaim_history_storage_api_audit_storage_reclaim_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HistoryStorageResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Reclaim History Storage",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/{audit_id}": {
      "get": {
        "description": "One history entry, with the `changes` it made worked out field by field.",
        "operationId": "get_audit_entry_api_audit__audit_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "audit_id",
            "required": true,
            "schema": {
              "title": "Audit Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditLogResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Audit Entry",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/audit/{audit_id}/revert": {
      "get": {
        "description": "Preview undoing a history entry without changing anything: which fields\nwould be put back, which were edited since (conflicts), and which cannot be\nput back. `blocked` says why when nothing can be undone at all.",
        "operationId": "plan_revert_api_audit__audit_id__revert_get",
        "parameters": [
          {
            "in": "path",
            "name": "audit_id",
            "required": true,
            "schema": {
              "title": "Audit Id",
              "type": "string"
            }
          },
          {
            "description": "Only plan these fields (repeat the parameter).",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only plan these fields (repeat the parameter).",
              "title": "Fields"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevertPlanResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Plan Revert",
        "tags": [
          "audit"
        ]
      },
      "post": {
        "description": "Undo a history entry on a record: an update puts the changed fields back,\na delete restores the record, a create deletes it. Goes through the normal\nrecord update, so the same rules apply and the revert is itself recorded\n(and can be reverted). Fields edited since the entry are left alone unless\n`force` is set.",
        "operationId": "revert_audit_entry_api_audit__audit_id__revert_post",
        "parameters": [
          {
            "in": "path",
            "name": "audit_id",
            "required": true,
            "schema": {
              "title": "Audit Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/RevertRequest"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevertResultResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Revert Audit Entry",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/automation": {
      "get": {
        "description": "Whether automation is paused, and how many runs are waiting or running.",
        "operationId": "automation_status_api_automation_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AutomationStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Automation Status",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/automation/resume": {
      "post": {
        "description": "Lift a pause. Triggers fire and queued runs are picked up again.",
        "operationId": "resume_automation_api_automation_resume_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AutomationStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Resume Automation",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/automation/stop": {
      "post": {
        "description": "Stop all automation, for example a workflow that keeps triggering itself.\n\nPauses automation (nothing new is triggered or started, and manual runs are\nrefused), cancels every waiting run, and stops every running one before its\nnext step. A step already in progress finishes or times out first. Call\n`POST /automation/resume` to start again.",
        "operationId": "stop_automation_api_automation_stop_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AutomationStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Stop Automation",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/collections": {
      "get": {
        "operationId": "list_datasets_api_collections_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/DatasetResponse"
                  },
                  "title": "Response List Datasets Api Collections Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Datasets",
        "tags": [
          "collections"
        ]
      },
      "post": {
        "operationId": "create_dataset_api_collections_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDatasetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Dataset",
        "tags": [
          "collections"
        ]
      }
    },
    "/api/collections/deleted": {
      "get": {
        "description": "Collections currently in Recently Deleted, most recently deleted first.",
        "operationId": "list_deleted_datasets_api_collections_deleted_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/DatasetResponse"
                  },
                  "title": "Response List Deleted Datasets Api Collections Deleted Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Deleted Datasets",
        "tags": [
          "collections"
        ]
      }
    },
    "/api/collections/{collection_name}/export.csv": {
      "get": {
        "description": "Export records in a collection as a CSV file, honoring the same\nfilters as the record list endpoint. One table for everything listed; to\nchoose the columns and format, or to take the files too, use\nPOST /file-access/zip with a `table`.",
        "operationId": "export_records_csv_api_collections__collection_name__export_csv_get",
        "parameters": [
          {
            "in": "path",
            "name": "collection_name",
            "required": true,
            "schema": {
              "title": "Collection Name",
              "type": "string"
            }
          },
          {
            "description": "Only records of this schema.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only records of this schema.",
              "title": "Schema"
            }
          },
          {
            "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
            "in": "query",
            "name": "within",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
              "title": "Within"
            }
          },
          {
            "description": "Record id (or prefix): direct children only, of any schema.",
            "in": "query",
            "name": "parent_record_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): direct children only, of any schema.",
              "title": "Parent Record Id"
            }
          },
          {
            "description": "Full-text search across all field values",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Full-text search across all field values",
              "title": "Search"
            }
          },
          {
            "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
            "in": "query",
            "name": "where",
            "required": false,
            "schema": {
              "default": [],
              "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
              "items": {
                "type": "string"
              },
              "title": "Where",
              "type": "array"
            }
          },
          {
            "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
              "title": "Filter"
            }
          },
          {
            "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": [],
              "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
              "items": {
                "type": "string"
              },
              "title": "Sort",
              "type": "array"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Export Records Csv",
        "tags": [
          "records"
        ]
      }
    },
    "/api/collections/{dataset_name}/records": {
      "delete": {
        "description": "Delete every record the query matches -- with no filters, all of the\ncollection's records (of 'schema', if given). The same filters as the\nlist endpoint, so \"delete all N matching\" deletes exactly what a list\nwith those filters shows.",
        "operationId": "delete_all_records_api_collections__dataset_name__records_delete",
        "parameters": [
          {
            "in": "path",
            "name": "dataset_name",
            "required": true,
            "schema": {
              "title": "Dataset Name",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "default": false,
              "title": "Force",
              "type": "boolean"
            }
          },
          {
            "description": "Only records of this schema.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only records of this schema.",
              "title": "Schema"
            }
          },
          {
            "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
            "in": "query",
            "name": "within",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
              "title": "Within"
            }
          },
          {
            "description": "Record id (or prefix): direct children only, of any schema.",
            "in": "query",
            "name": "parent_record_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): direct children only, of any schema.",
              "title": "Parent Record Id"
            }
          },
          {
            "description": "Full-text search across all field values",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Full-text search across all field values",
              "title": "Search"
            }
          },
          {
            "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
            "in": "query",
            "name": "where",
            "required": false,
            "schema": {
              "default": [],
              "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
              "items": {
                "type": "string"
              },
              "title": "Where",
              "type": "array"
            }
          },
          {
            "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
              "title": "Filter"
            }
          },
          {
            "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": [],
              "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
              "items": {
                "type": "string"
              },
              "title": "Sort",
              "type": "array"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete All Records",
        "tags": [
          "records"
        ]
      },
      "get": {
        "description": "List records in a collection, paginated, filtered and sorted.\n\n'where' and 'filter' can be combined -- the equality checks from 'where'\nare AND-combined with the 'filter' tree, if both are given.",
        "operationId": "list_records_api_collections__dataset_name__records_get",
        "parameters": [
          {
            "in": "path",
            "name": "dataset_name",
            "required": true,
            "schema": {
              "title": "Dataset Name",
              "type": "string"
            }
          },
          {
            "description": "Repeatable column names whose values aren't in a record's own 'data' -- inherited fields and 'ref_field.target_field' joins -- returned under each record's 'derived'.",
            "in": "query",
            "name": "columns",
            "required": false,
            "schema": {
              "default": [],
              "description": "Repeatable column names whose values aren't in a record's own 'data' -- inherited fields and 'ref_field.target_field' joins -- returned under each record's 'derived'.",
              "items": {
                "type": "string"
              },
              "title": "Columns",
              "type": "array"
            }
          },
          {
            "description": "Attach each record's live child count per child schema.",
            "in": "query",
            "name": "child_counts",
            "required": false,
            "schema": {
              "default": false,
              "description": "Attach each record's live child count per child schema.",
              "title": "Child Counts",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 1000,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "description": "Only records of this schema.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only records of this schema.",
              "title": "Schema"
            }
          },
          {
            "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
            "in": "query",
            "name": "within",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
              "title": "Within"
            }
          },
          {
            "description": "Record id (or prefix): direct children only, of any schema.",
            "in": "query",
            "name": "parent_record_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): direct children only, of any schema.",
              "title": "Parent Record Id"
            }
          },
          {
            "description": "Full-text search across all field values",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Full-text search across all field values",
              "title": "Search"
            }
          },
          {
            "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
            "in": "query",
            "name": "where",
            "required": false,
            "schema": {
              "default": [],
              "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
              "items": {
                "type": "string"
              },
              "title": "Where",
              "type": "array"
            }
          },
          {
            "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
              "title": "Filter"
            }
          },
          {
            "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": [],
              "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
              "items": {
                "type": "string"
              },
              "title": "Sort",
              "type": "array"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedRecordResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Records",
        "tags": [
          "records"
        ]
      },
      "post": {
        "operationId": "create_record_api_collections__dataset_name__records_post",
        "parameters": [
          {
            "in": "path",
            "name": "dataset_name",
            "required": true,
            "schema": {
              "title": "Dataset Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRecordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Record",
        "tags": [
          "records"
        ]
      }
    },
    "/api/collections/{name_or_id}": {
      "get": {
        "operationId": "get_dataset_api_collections__name_or_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "name_or_id",
            "required": true,
            "schema": {
              "title": "Name Or Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Dataset",
        "tags": [
          "collections"
        ]
      },
      "patch": {
        "operationId": "update_dataset_api_collections__name_or_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "name_or_id",
            "required": true,
            "schema": {
              "title": "Name Or Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDatasetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Dataset",
        "tags": [
          "collections"
        ]
      }
    },
    "/api/collections/{name_or_id}/audit": {
      "get": {
        "description": "Audit entries for a collection \u2014 renames, description changes,\ndelete/restore/purge \u2014 most recent first.",
        "operationId": "list_dataset_audit_api_collections__name_or_id__audit_get",
        "parameters": [
          {
            "in": "path",
            "name": "name_or_id",
            "required": true,
            "schema": {
              "title": "Name Or Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 1000,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "description": "Only entries of this action (create, update, ...).",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries of this action (create, update, ...).",
              "title": "Action"
            }
          },
          {
            "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
              "title": "Sort"
            }
          },
          {
            "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
              "title": "Since"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedAuditLogResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Dataset Audit",
        "tags": [
          "collections"
        ]
      }
    },
    "/api/collections/{name_or_id}/record-counts": {
      "get": {
        "description": "Record counts grouped by schema name \u2014 single SQL GROUP BY, no record\nloading. Takes the list endpoint's filters (except 'schema', which is the\ngrouping), so e.g. 'within' counts what sits under one record.",
        "operationId": "record_counts_api_collections__name_or_id__record_counts_get",
        "parameters": [
          {
            "in": "path",
            "name": "name_or_id",
            "required": true,
            "schema": {
              "title": "Name Or Id",
              "type": "string"
            }
          },
          {
            "description": "Only records of this schema.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only records of this schema.",
              "title": "Schema"
            }
          },
          {
            "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
            "in": "query",
            "name": "within",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
              "title": "Within"
            }
          },
          {
            "description": "Record id (or prefix): direct children only, of any schema.",
            "in": "query",
            "name": "parent_record_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): direct children only, of any schema.",
              "title": "Parent Record Id"
            }
          },
          {
            "description": "Full-text search across all field values",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Full-text search across all field values",
              "title": "Search"
            }
          },
          {
            "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
            "in": "query",
            "name": "where",
            "required": false,
            "schema": {
              "default": [],
              "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
              "items": {
                "type": "string"
              },
              "title": "Where",
              "type": "array"
            }
          },
          {
            "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
              "title": "Filter"
            }
          },
          {
            "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": [],
              "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
              "items": {
                "type": "string"
              },
              "title": "Sort",
              "type": "array"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Record Counts",
        "tags": [
          "collections"
        ]
      }
    },
    "/api/collections/{name}": {
      "delete": {
        "operationId": "delete_dataset_api_collections__name__delete",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Dataset",
        "tags": [
          "collections"
        ]
      }
    },
    "/api/collections/{name}/purge": {
      "delete": {
        "operationId": "purge_dataset_api_collections__name__purge_delete",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Purge Dataset",
        "tags": [
          "collections"
        ]
      }
    },
    "/api/collections/{name}/restore": {
      "post": {
        "operationId": "restore_dataset_api_collections__name__restore_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Dataset",
        "tags": [
          "collections"
        ]
      }
    },
    "/api/collections/{name}/restore-plan": {
      "get": {
        "description": "What restoring a deleted collection would bring back: it and the records\ndeleted with it, not records deleted on their own earlier.",
        "operationId": "restore_dataset_plan_api_collections__name__restore_plan_get",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestorePlanResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Dataset Plan",
        "tags": [
          "collections"
        ]
      }
    },
    "/api/db/config": {
      "patch": {
        "operationId": "set_url_api_db_config_patch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetDbUrlRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DbStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Url",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/docker/setup": {
      "post": {
        "operationId": "docker_setup_api_db_docker_setup_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DbStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Docker Setup",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/docker/teardown": {
      "post": {
        "description": "Removes the Docker container and its data volume, but leaves\nconfig.toml pointed at it \u2014 mirrors `civex db teardown`'s own warning\nthat a subsequent setup-docker/--sqlite is needed to keep using this\nproject. Returns the (now-broken) status so the UI can show what\nhappened rather than a bare 204.",
        "operationId": "docker_teardown_api_db_docker_teardown_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DbStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Docker Teardown",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/migrate": {
      "post": {
        "operationId": "migrate_api_db_migrate_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DbStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Migrate",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/move": {
      "post": {
        "description": "Start copying the project's data into the destination, in the\nbackground; poll `GET /db/move/{id}`. Only when the copy has been verified\ndoes the project switch to the new database, and the old one is never\nmodified, so a move can always be undone.",
        "operationId": "start_move_api_db_move_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MoveTargetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MoveJobResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Start Move",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/move/preflight": {
      "post": {
        "description": "What moving to this destination would do, and whether it can -- with\nno side effects: nothing is created, started or written.",
        "operationId": "move_preflight_api_db_move_preflight_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MoveTargetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MovePreflightResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Move Preflight",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/move/{job_id}": {
      "get": {
        "description": "Progress and outcome of a move started with `POST /db/move`.",
        "operationId": "get_move_api_db_move__job_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MoveJobResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Move",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/move/{job_id}/cancel": {
      "post": {
        "description": "Ask a running move to stop. Nothing is changed: the copy is one\ntransaction, and the project keeps using its current database.",
        "operationId": "cancel_move_api_db_move__job_id__cancel_post",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MoveJobResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Cancel Move",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/moves": {
      "get": {
        "description": "Past database moves, newest first.",
        "operationId": "list_moves_api_db_moves_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/MoveRecordResponse"
                  },
                  "title": "Response List Moves Api Db Moves Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Moves",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/moves/{move_id}/revert": {
      "post": {
        "description": "Point the project back at the database a move came from. Nothing is\ncopied: anything written to the new database since stays there.",
        "operationId": "revert_move_api_db_moves__move_id__revert_post",
        "parameters": [
          {
            "in": "path",
            "name": "move_id",
            "required": true,
            "schema": {
              "title": "Move Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DbStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Revert Move",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/status": {
      "get": {
        "operationId": "get_status_api_db_status_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DbStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Status",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/summary": {
      "get": {
        "description": "What is in the database now in use: its kind, location, size and\nrecord count.",
        "operationId": "get_summary_api_db_summary_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatabaseSummaryResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Summary",
        "tags": [
          "db"
        ]
      }
    },
    "/api/db/test-connection": {
      "post": {
        "description": "Check a PostgreSQL server's details connect, and say in plain words\nwhat is wrong if they don't.",
        "operationId": "test_connection_api_db_test_connection_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MoveTargetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectionCheckResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Test Connection",
        "tags": [
          "db"
        ]
      }
    },
    "/api/dump": {
      "get": {
        "description": "Export all schemas, datasets, records, and workflows as a YAML file download.",
        "operationId": "export_dump_api_dump_get",
        "parameters": [
          {
            "in": "query",
            "name": "no_data",
            "required": false,
            "schema": {
              "default": false,
              "title": "No Data",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Export Dump",
        "tags": [
          "dump"
        ]
      }
    },
    "/api/file-access/definitions": {
      "get": {
        "description": "The saved exports to offer where the person is: on a record of `schema`\n(those saved with it or a schema above it whose files are at or beneath it),\nor on a `collection` (those saved with any schema it is for). Give neither for\nevery saved export. Run one with `export` as `schema/name` and `collection`\nand/or `within`.",
        "operationId": "available_definitions_api_file_access_definitions_get",
        "parameters": [
          {
            "description": "A schema name: the exports that can run within a record of it.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A schema name: the exports that can run within a record of it.",
              "title": "Schema"
            }
          },
          {
            "description": "A collection name: the exports saved with its schemas.",
            "in": "query",
            "name": "collection",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A collection name: the exports saved with its schemas.",
              "title": "Collection"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ExportDefinitionResponse"
                  },
                  "title": "Response Available Definitions Api File Access Definitions Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Available Definitions",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/download": {
      "post": {
        "description": "Download the picked files that are only on the server to this computer\n(onto their collection's drive). Answers when they have arrived: how many\ncame and which the server hasn't got yet.",
        "operationId": "download_files_api_file_access_download_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FilePickRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Download Files",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/export": {
      "post": {
        "description": "Build the selection as a folder tree on the server's machine.\n\n`link` makes hard links in a folder on the drive that holds the files;\n`copy` makes copies on the drive named by `volume`. Answers 409, building\nnothing, when files are out of reach (`files_unavailable`, unless\n`allow_partial`), when they are on several drives and a link was asked for\n(`files_scattered`), or when the drive can't hold links\n(`links_not_possible`). Building again into the same folder updates it.",
        "operationId": "export_files_api_file_access_export_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileExportRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Export Files",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/exports": {
      "get": {
        "description": "The export folders civex made, newest first, in the project and on each\nconnected drive: where they are, how many files, and how much space they\ntake (links take none; copies do). Exports on a drive that isn't connected\ncan't be listed.",
        "operationId": "list_exports_api_file_access_exports_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Exports",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/exports/remove": {
      "post": {
        "description": "Delete export folders: the links or copies the export made, then the\nfolder. A link is removed without touching the stored file it points at.\nFiles in the folder that the export didn't make are left, with the folder.\nA path that isn't an export folder is refused (listed under `errors`).",
        "operationId": "remove_exports_api_file_access_exports_remove_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RemoveExportsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Remove Exports",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/files": {
      "post": {
        "description": "A page of a selection's files, one row per file as stored (a file\nseveral records use is one row: `uses` lists those records, each with the\nnames of the records above it, `trail`; `others` counts the records\noutside the selection that use it too), each with where it is (`place`: a\ndrive's name, `server` or `missing`; `place_kind`: drive, unreachable,\nserver or missing), narrowed by place, name (the file's, or any record's\nit sits under) and the selection's own filter; and `summary`, where all\nof the selection's files are, by place. Counts are of files.",
        "operationId": "list_files_api_file_access_files_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileListRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Files",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/free-up": {
      "post": {
        "description": "Remove this computer's copies of the picked files to free space; each\ncomes back when opened or exported. Only files the server confirms it\nholds, and never one a collection kept on this computer uses (switch that\ncollection to fetch when opened first). Counts unless `dry_run=false`.",
        "operationId": "free_up_files_api_file_access_free_up_post",
        "parameters": [
          {
            "description": "Only count (the default).",
            "in": "query",
            "name": "dry_run",
            "required": false,
            "schema": {
              "default": true,
              "description": "Only count (the default).",
              "title": "Dry Run",
              "type": "boolean"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FilePickRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Free Up Files",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/gather": {
      "post": {
        "description": "Move the picked files onto one drive: a selection's files, narrowed by\nplace, name or ticked files (`shas`). Only those move; the rest of their\ncollections stay where they are. Files only on the server are downloaded\nfirst; files on a drive that can't be reached, or missing, are left out. It\nruns like any other move (one at a time, safe to pause, cancel or lose\npower; see /store/transfers). Files downloaded straight onto the drive need\nno move: when nothing else has to move, `transfer_id` is null and\n`downloaded` says how many came. Files that records not picked also use\nstay where they are unless `include_shared` (`shared_left` says how\nmany). With `dry_run`, only `plan` is answered and nothing is done. 422\nwhen they are all already there.",
        "operationId": "gather_files_api_file_access_gather_post",
        "parameters": [
          {
            "description": "Only say what the move would do.",
            "in": "query",
            "name": "dry_run",
            "required": false,
            "schema": {
              "default": false,
              "description": "Only say what the move would do.",
              "title": "Dry Run",
              "type": "boolean"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileGatherRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Gather Files",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/plan": {
      "post": {
        "description": "What a selection holds, each file named by its place in the record\nhierarchy, and what can be reached right now. Makes nothing: this is what to\nshow a person before they are pointed at a folder.",
        "operationId": "plan_files_api_file_access_plan_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FilePlanRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Plan Files",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/progress/{progress_id}": {
      "get": {
        "description": "How far a request tagged with this id has got: the stage it is in, how many\nsteps it has done of how many (0 when that isn't known yet), and whether it has\nfinished. 404 until the request has begun, and again a little after it ends.",
        "operationId": "get_progress_api_file_access_progress__progress_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "progress_id",
            "required": true,
            "schema": {
              "title": "Progress Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Progress",
        "tags": [
          "files"
        ]
      }
    },
    "/api/file-access/zip": {
      "post": {
        "description": "The selection as something to download, with the same paths and tables as\nan export -- for someone who can't see the server's disk: a zip of the files\nand their tables, or, when the selection is a single table and nothing else,\nthat table itself. Unreachable files answer 409 unless `allow_partial` is\nset, and are then listed in MISSING.txt.",
        "operationId": "zip_files_api_file_access_zip_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileZipRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Zip Files",
        "tags": [
          "files"
        ]
      }
    },
    "/api/files": {
      "post": {
        "description": "Upload a multipart file. Starlette has already spooled the body to a\ntemp file by the time this runs; it is hashed and copied into the object\nstore 1 MiB at a time, so memory use is independent of file size.",
        "operationId": "upload_file_api_files_post",
        "parameters": [
          {
            "description": "Id of the collection the file is for. It only steers which volume receives *new* content (the collection's home volume, if it has one); a file whose content is already stored is reused where it lives, never copied again.",
            "in": "query",
            "name": "collection",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Id of the collection the file is for. It only steers which volume receives *new* content (the collection's home volume, if it has one); a file whose content is already stored is reused where it lives, never copied again.",
              "title": "Collection"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_upload_file_api_files_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileRefResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Upload File",
        "tags": [
          "files"
        ]
      }
    },
    "/api/files/stream": {
      "put": {
        "description": "Upload a raw (non-multipart) request body, streamed straight to the\nobject store instead of buffered in memory first. A multipart body sent\nvia POST / has to be fully spooled to a temp file by Starlette's form\nparser before this code ever runs -- reading it back into memory here\nwould mean the bytes touch disk twice for no reason. Sending the raw\nbody instead lets us read it directly off the wire in chunks, and\n(unlike multipart, where per-part sizes aren't available upfront) a raw\nbody carries an accurate Content-Length the object store can use to\npick a volume with enough room before writing a single byte.",
        "operationId": "upload_file_stream_api_files_stream_put",
        "parameters": [
          {
            "in": "query",
            "name": "filename",
            "required": false,
            "schema": {
              "default": "upload",
              "title": "Filename",
              "type": "string"
            }
          },
          {
            "description": "Id of the collection the file is for. It only steers which volume receives *new* content (the collection's home volume, if it has one); a file whose content is already stored is reused where it lives, never copied again.",
            "in": "query",
            "name": "collection",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Id of the collection the file is for. It only steers which volume receives *new* content (the collection's home volume, if it has one); a file whose content is already stored is reused where it lives, never copied again.",
              "title": "Collection"
            }
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileRefResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Upload File Stream",
        "tags": [
          "files"
        ]
      }
    },
    "/api/files/{sha256}": {
      "get": {
        "description": "Fetch raw file bytes by content hash.\n\nThis endpoint is content-addressed only \u2014 it has no notion of which\nrecord/field a download is \"for\", so it can't apply a `filename_template`\nresolution itself. Callers that want a resolved `Content-Disposition`\nfilename (e.g. scripted access) should read `resolved_filename` off the\nrecord via the records API and pass it as `?filename=`; the record-UI\ndownload link does this implicitly via the `download` attribute.",
        "operationId": "download_file_api_files__sha256__get",
        "parameters": [
          {
            "in": "path",
            "name": "sha256",
            "required": true,
            "schema": {
              "title": "Sha256",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "filename",
            "required": false,
            "schema": {
              "default": "",
              "title": "Filename",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Download File",
        "tags": [
          "files"
        ]
      }
    },
    "/api/files/{sha256}/info": {
      "get": {
        "description": "Where a file's content is stored and what uses it.\n\nLists every place the content is, or is recorded to be (each volume, its\nstate, and the object's path on it, including a volume that is unplugged\nright now), the size, and the records, collections and workflow runs that\nuse it. A file used by several records is stored once, so this is how to\nsee everything that shares it.",
        "operationId": "file_info_api_files__sha256__info_get",
        "parameters": [
          {
            "in": "path",
            "name": "sha256",
            "required": true,
            "schema": {
              "title": "Sha256",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileInfoResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "File Info",
        "tags": [
          "files"
        ]
      }
    },
    "/api/jobs": {
      "get": {
        "description": "`record_id` filters to runs *triggered by* that record; `affected_record_id`\nfilters to runs that created or updated that record -- the two directions of\nthe run/record audit trail (a record can be both for different runs).\n`affected_schema` filters to runs that wrote to that schema (indexed).\nResults are paginated: `limit` defaults to 50 and is capped at 500.",
        "operationId": "list_jobs_api_jobs_get",
        "parameters": [
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Status"
            }
          },
          {
            "in": "query",
            "name": "record_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Record Id"
            }
          },
          {
            "in": "query",
            "name": "affected_record_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Affected Record Id"
            }
          },
          {
            "in": "query",
            "name": "affected_schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Affected Schema"
            }
          },
          {
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Trigger"
            }
          },
          {
            "description": "Only runs of the workflow with exactly this name.",
            "in": "query",
            "name": "workflow",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only runs of the workflow with exactly this name.",
              "title": "Workflow"
            }
          },
          {
            "description": "Match on workflow name or error text.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Match on workflow name or error text.",
              "title": "Search"
            }
          },
          {
            "description": "A filter tree as JSON (`{\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"failed\"}]}`), the same shape as the records filter. Fields come from GET /jobs/filter-fields.",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A filter tree as JSON (`{\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"failed\"}]}`), the same shape as the records filter. Fields come from GET /jobs/filter-fields.",
              "title": "Filter"
            }
          },
          {
            "description": "'column[:asc|desc]' over workflow_name, status, trigger, schema_name, created_at. Newest first otherwise.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "'column[:asc|desc]' over workflow_name, status, trigger, schema_name, created_at. Newest first otherwise.",
              "title": "Sort"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/WorkflowJobResponse"
                  },
                  "title": "Response List Jobs Api Jobs Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Jobs",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/jobs/count": {
      "get": {
        "operationId": "count_jobs_api_jobs_count_get",
        "parameters": [
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Status"
            }
          },
          {
            "in": "query",
            "name": "record_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Record Id"
            }
          },
          {
            "in": "query",
            "name": "affected_record_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Affected Record Id"
            }
          },
          {
            "in": "query",
            "name": "affected_schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Affected Schema"
            }
          },
          {
            "in": "query",
            "name": "trigger",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Trigger"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Search"
            }
          },
          {
            "in": "query",
            "name": "workflow",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Workflow"
            }
          },
          {
            "description": "A filter tree as JSON (`{\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"failed\"}]}`), the same shape as the records filter. Fields come from GET /jobs/filter-fields.",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A filter tree as JSON (`{\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"failed\"}]}`), the same shape as the records filter. Fields come from GET /jobs/filter-fields.",
              "title": "Filter"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Count Jobs",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/jobs/delete": {
      "post": {
        "description": "Delete runs, whatever their state. A waiting run never starts; a running\none stops before its next step; a finished one is removed with its step\nlog. What a run already changed in records stays (and is in their history).",
        "operationId": "delete_jobs_api_jobs_delete_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeleteJobsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteJobsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Jobs",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/jobs/drain": {
      "post": {
        "description": "Kick off the worker to process all pending jobs.",
        "operationId": "drain_jobs_api_jobs_drain_post",
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Drain Jobs",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/jobs/failure-groups": {
      "get": {
        "description": "Failed runs grouped by workflow and what went wrong, most first, so a\nthousand failures read as the few causes they are. `filter` narrows which\nruns are counted (only failed ones ever are).",
        "operationId": "failure_groups_api_jobs_failure_groups_get",
        "parameters": [
          {
            "description": "A filter tree as JSON (`{\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"failed\"}]}`), the same shape as the records filter. Fields come from GET /jobs/filter-fields.",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A filter tree as JSON (`{\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"failed\"}]}`), the same shape as the records filter. Fields come from GET /jobs/filter-fields.",
              "title": "Filter"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/FailureGroupResponse"
                  },
                  "title": "Response Failure Groups Api Jobs Failure Groups Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Failure Groups",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/jobs/filter-fields": {
      "get": {
        "description": "The fields a run filter may test, with their types and operators.",
        "operationId": "run_filter_fields_api_jobs_filter_fields_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/RunFieldResponse"
                  },
                  "title": "Response Run Filter Fields Api Jobs Filter Fields Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Run Filter Fields",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/jobs/rerun": {
      "post": {
        "description": "Repeat several runs at once: each is queued as a new run of the same\nworkflow on the same record, with the same input. One request, one commit and\none pass of the worker, however many. A run that cannot be repeated (a bad id,\nan unknown run, a record that has since been deleted) is listed under\n`skipped` with the reason, and the rest are still queued. Refused (422) while\nautomation is paused.",
        "operationId": "rerun_jobs_api_jobs_rerun_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RerunJobsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RerunJobsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Rerun Jobs",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/jobs/{job_id}": {
      "delete": {
        "description": "Delete one run, whatever its state (see POST /jobs/delete).",
        "operationId": "delete_job_api_jobs__job_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Job",
        "tags": [
          "jobs"
        ]
      },
      "get": {
        "operationId": "get_job_api_jobs__job_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowJobResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Job",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/jobs/{job_id}/cancel": {
      "post": {
        "description": "Cancel one run. A waiting run never starts; a running one stops before\nits next step (a step already in progress finishes or times out first). A\nrun that has already finished is returned unchanged.",
        "operationId": "cancel_job_api_jobs__job_id__cancel_post",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowJobResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Cancel Job",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/jobs/{job_id}/rerun": {
      "post": {
        "description": "Enqueue a new job using the same workflow and record as an existing job.",
        "operationId": "rerun_job_api_jobs__job_id__rerun_post",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowJobResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Rerun Job",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/legal/license": {
      "get": {
        "description": "The software's own license text -- independent of any project, so\nthis doesn't go through Depends(get_ctx).",
        "operationId": "get_license_api_legal_license_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get License",
        "tags": [
          "legal"
        ]
      }
    },
    "/api/legal/policies": {
      "get": {
        "description": "Org-authored data/governance policy documents from _civex/policies/.",
        "operationId": "list_policies_api_legal_policies_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/PolicyResponse"
                  },
                  "title": "Response List Policies Api Legal Policies Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Policies",
        "tags": [
          "legal"
        ]
      }
    },
    "/api/legal/policies/{stem}": {
      "get": {
        "operationId": "get_policy_api_legal_policies__stem__get",
        "parameters": [
          {
            "in": "path",
            "name": "stem",
            "required": true,
            "schema": {
              "title": "Stem",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Policy",
        "tags": [
          "legal"
        ]
      }
    },
    "/api/plugins": {
      "get": {
        "description": "List all registered plugins (built-ins + user plugins from _civex/plugins/).",
        "operationId": "list_plugins_api_plugins_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/PluginInfo"
                  },
                  "title": "Response List Plugins Api Plugins Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Plugins",
        "tags": [
          "plugins"
        ]
      },
      "post": {
        "description": "Save a plugin from JSON source (used by the AI confirmation UI and the\nTier 1 plugin editor). Writes the file, then re-registers it -- which\ndescribes it in the same request, so a broken contract surfaces\nimmediately as an error response rather than only on next use.",
        "operationId": "save_plugin_json_api_plugins_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PluginSaveRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Save Plugin Json",
        "tags": [
          "plugins"
        ]
      }
    },
    "/api/plugins/containers": {
      "get": {
        "description": "List Tier 2 (container) plugin directories under _civex/plugins/.",
        "operationId": "list_container_plugins_api_plugins_containers_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ContainerPluginInfo"
                  },
                  "title": "Response List Container Plugins Api Plugins Containers Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Container Plugins",
        "tags": [
          "plugins"
        ]
      }
    },
    "/api/plugins/containers/{name}": {
      "get": {
        "description": "Full file tree (Dockerfile + source) of a container plugin.",
        "operationId": "get_container_plugin_api_plugins_containers__name__get",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContainerPluginDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Container Plugin",
        "tags": [
          "plugins"
        ]
      },
      "put": {
        "description": "Save one file in the plugin's directory, then rebuild its Docker\nimage immediately -- the multi-file equivalent of Tier 1's save-triggers-\ndescribe round-trip.",
        "operationId": "save_container_plugin_file_api_plugins_containers__name__put",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContainerFileSaveRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BuildResult"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Save Container Plugin File",
        "tags": [
          "plugins"
        ]
      }
    },
    "/api/plugins/errors": {
      "get": {
        "description": "List user plugin files that failed discovery -- these have no plugin\nid and so never appear in GET /plugins, but the frontend plugin panel\nstill needs to show why they're missing.",
        "operationId": "list_plugin_load_errors_api_plugins_errors_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/PluginLoadError"
                  },
                  "title": "Response List Plugin Load Errors Api Plugins Errors Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Plugin Load Errors",
        "tags": [
          "plugins"
        ]
      }
    },
    "/api/plugins/upload": {
      "post": {
        "description": "Upload a .py plugin file into _civex/plugins/ and register it immediately.",
        "operationId": "upload_plugin_api_plugins_upload_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_upload_plugin_api_plugins_upload_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResult"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Upload Plugin",
        "tags": [
          "plugins"
        ]
      }
    },
    "/api/plugins/{filename}": {
      "delete": {
        "description": "Delete a user plugin file. Refuses to delete built-ins (they have no\nfile to delete, and 404) and any plugin still referenced by a workflow\nstep (409), unless `force` is set.",
        "operationId": "delete_plugin_api_plugins__filename__delete",
        "parameters": [
          {
            "in": "path",
            "name": "filename",
            "required": true,
            "schema": {
              "title": "Filename",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "default": false,
              "title": "Force",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Plugin",
        "tags": [
          "plugins"
        ]
      }
    },
    "/api/plugins/{filename}/source": {
      "get": {
        "description": "Read a single user plugin's raw source, e.g. to populate the editor.",
        "operationId": "get_plugin_source_api_plugins__filename__source_get",
        "parameters": [
          {
            "in": "path",
            "name": "filename",
            "required": true,
            "schema": {
              "title": "Filename",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginSource"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Plugin Source",
        "tags": [
          "plugins"
        ]
      }
    },
    "/api/records": {
      "get": {
        "operationId": "search_records_global_api_records_get",
        "parameters": [
          {
            "description": "Schema name to search within",
            "in": "query",
            "name": "schema",
            "required": true,
            "schema": {
              "description": "Schema name to search within",
              "title": "Schema",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Search"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "description": "Collection name: only records a record in that collection may reference -- its own collection's and those of global collections. What a reference picker should pass.",
            "in": "query",
            "name": "reachable_from",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Collection name: only records a record in that collection may reference -- its own collection's and those of global collections. What a reference picker should pass.",
              "title": "Reachable From"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/RecordResponse"
                  },
                  "title": "Response Search Records Global Api Records Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Search Records Global",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/bulk-delete": {
      "post": {
        "operationId": "bulk_delete_records_api_records_bulk_delete_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Body_bulk_delete_records_api_records_bulk_delete_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Bulk Delete Records",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/deleted": {
      "get": {
        "description": "Records currently in Recently Deleted, most recently deleted first.\nPaginated: `limit` defaults to 200 and is capped at 1000.",
        "operationId": "list_deleted_records_api_records_deleted_get",
        "parameters": [
          {
            "description": "Limit to records from this collection",
            "in": "query",
            "name": "dataset",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Limit to records from this collection",
              "title": "Dataset"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 200,
              "maximum": 1000,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/RecordResponse"
                  },
                  "title": "Response List Deleted Records Api Records Deleted Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Deleted Records",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/labels": {
      "post": {
        "description": "Names for a batch of record ids, as they are now.\n\nAnywhere that kept only a record's id (a workflow run's records, a pinned\nrecord, a link) asks here for its name instead of keeping a copy that would\ngo stale when the record or its schema's name template changes. One call\nresolves any number of ids (up to 200); ids that aren't records, or whose\nrecord no longer exists, are omitted. Read-only: it is a POST only so the\nids travel in the body rather than a long address.",
        "operationId": "record_labels_api_records_labels_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordLabelsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/RecordLabelResponse"
                  },
                  "title": "Response Record Labels Api Records Labels Post",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Record Labels",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/orphans": {
      "get": {
        "description": "Live records that sit under a deleted record, so nothing above them lists\nthem: each with what it sits under. Restore that with\nPOST /records/{id}/restore-above, or delete the record.",
        "operationId": "list_orphans_api_records_orphans_get",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 200,
              "maximum": 1000,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrphansResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Orphans",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/restore-selected": {
      "post": {
        "description": "Restore exactly these deleted records, not what was deleted alongside\nthem: for taking back three of the sixty records one delete took. The\ndeleted records above a chosen one come back too (each by itself) unless\n`with_parents` is false, in which case such a record is left.",
        "operationId": "restore_selected_records_api_records_restore_selected_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestoreSelectedRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestoreSelectedResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Selected Records",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/search": {
      "get": {
        "description": "Search records of every schema in one query, best match first -- what\nthe web UI's jump-to box uses. Each result's `collection` says where it\nlives. Records that are deleted, or in a deleted collection or schema,\nare never returned.",
        "operationId": "search_records_api_records_search_get",
        "parameters": [
          {
            "description": "Text to find in a record's values, or the start of its id.",
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "description": "Text to find in a record's values, or the start of its id.",
              "minLength": 1,
              "title": "Q",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "description": "Collection name: only search records in it. Omitted, every collection is searched.",
            "in": "query",
            "name": "collection",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Collection name: only search records in it. Omitted, every collection is searched.",
              "title": "Collection"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/RecordResponse"
                  },
                  "title": "Response Search Records Api Records Search Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Search Records",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/{record_id}": {
      "delete": {
        "operationId": "delete_record_api_records__record_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "default": false,
              "title": "Force",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Record",
        "tags": [
          "records"
        ]
      },
      "get": {
        "operationId": "get_record_api_records__record_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Record",
        "tags": [
          "records"
        ]
      },
      "patch": {
        "operationId": "update_record_api_records__record_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRecordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Record",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/{record_id}/audit": {
      "get": {
        "description": "Audit entries for a single record \u2014 every create/update/delete recorded\nagainst it, most recent first.",
        "operationId": "list_record_audit_api_records__record_id__audit_get",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 1000,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "description": "Only entries of this action (create, update, ...).",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries of this action (create, update, ...).",
              "title": "Action"
            }
          },
          {
            "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
              "title": "Sort"
            }
          },
          {
            "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
              "title": "Since"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedAuditLogResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Record Audit",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/records/{record_id}/files.zip": {
      "get": {
        "description": "Bundle a record's files into a zip, one entry per file, named with the\nsame `resolved_filename` used for single-file download. Entries that\nwould collide (e.g. two files resolving to the same template output) get\na numeric suffix rather than overwriting each other in the archive.",
        "operationId": "export_record_files_zip_api_records__record_id__files_zip_get",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          },
          {
            "description": "Limit the export to a single file/file_list field; omit for every file on the record",
            "in": "query",
            "name": "field",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Limit the export to a single file/file_list field; omit for every file on the record",
              "title": "Field"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Export Record Files Zip",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/{record_id}/purge": {
      "delete": {
        "operationId": "purge_record_api_records__record_id__purge_delete",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Purge Record",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/{record_id}/referrers": {
      "get": {
        "description": "What points at this record: live records referencing it through a\n`reference` or `reference_list` field, counted per (collection, schema,\nfield) -- the reverse of the record's own reference values.",
        "operationId": "get_record_referrers_api_records__record_id__referrers_get",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ReferrerGroupResponse"
                  },
                  "title": "Response Get Record Referrers Api Records  Record Id  Referrers Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Record Referrers",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/{record_id}/restore": {
      "post": {
        "description": "Restore a deleted record with what was deleted alongside it. Refused while\nits collection or schema is deleted, or a record above it is (unless\n`with_parents`).",
        "operationId": "restore_record_api_records__record_id__restore_post",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          },
          {
            "description": "Restore just this record, not what was deleted alongside it (its children).",
            "in": "query",
            "name": "only_this",
            "required": false,
            "schema": {
              "default": false,
              "description": "Restore just this record, not what was deleted alongside it (its children).",
              "title": "Only This",
              "type": "boolean"
            }
          },
          {
            "description": "When only deleted records above this one hold it back, restore them too, each by itself, so its deleted siblings stay deleted.",
            "in": "query",
            "name": "with_parents",
            "required": false,
            "schema": {
              "default": false,
              "description": "When only deleted records above this one hold it back, restore them too, each by itself, so its deleted siblings stay deleted.",
              "title": "With Parents",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Record",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/{record_id}/restore-above": {
      "post": {
        "description": "Bring back what a live record sits under that is deleted: each deleted\nrecord directly above it, by itself, so their other children stay deleted.\nRefused (422) while the collection or schema of the topmost is deleted, or\nwhen one would clash with a live record's unique key.",
        "operationId": "restore_above_api_records__record_id__restore_above_post",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/RecordResponse"
                  },
                  "title": "Response Restore Above Api Records  Record Id  Restore Above Post",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Above",
        "tags": [
          "records"
        ]
      }
    },
    "/api/records/{record_id}/restore-plan": {
      "get": {
        "description": "What restoring a deleted record would do, without doing it: how many\nrecords come back with it (those deleted together with it), the collection\nit will be in, and `blocked_by` when its collection, schema or a parent\nrecord is still deleted and must be restored first.",
        "operationId": "restore_record_plan_api_records__record_id__restore_plan_get",
        "parameters": [
          {
            "in": "path",
            "name": "record_id",
            "required": true,
            "schema": {
              "title": "Record Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestorePlanResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Record Plan",
        "tags": [
          "records"
        ]
      }
    },
    "/api/remote": {
      "get": {
        "description": "How this project stands with its authority.",
        "operationId": "status_api_remote_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RemoteStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Status",
        "tags": [
          "sync"
        ]
      },
      "patch": {
        "description": "Pause or resume the schedule, change how often it looks, or choose which\nfiles this device keeps a copy of.",
        "operationId": "update_api_remote_patch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RemoteUpdateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RemoteStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/authority": {
      "get": {
        "description": "Whether this project accepts devices, the devices that joined, and the\ninvites waiting.",
        "operationId": "authority_api_remote_authority_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthorityResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Authority",
        "tags": [
          "sync"
        ]
      },
      "patch": {
        "description": "Start or stop accepting devices (the devices stay on record), and say\nwhat the library takes from them.",
        "operationId": "update_authority_api_remote_authority_patch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthorityUpdateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthorityResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Authority",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/authority/devices/{name}/publish": {
      "post": {
        "description": "Let a device publish to the library, or stop it.",
        "operationId": "allow_publish_api_remote_authority_devices__name__publish_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DevicePublishRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthorityResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Allow Publish",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/authority/devices/{name}/revoke": {
      "post": {
        "description": "Stop a device syncing, at once: its session is refused from now on.",
        "operationId": "revoke_device_api_remote_authority_devices__name__revoke_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthorityResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Revoke Device",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/authority/invites": {
      "post": {
        "description": "Invite a device. The answer is the only time the invite is shown.",
        "operationId": "invite_device_api_remote_authority_invites_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvitedResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Invite Device",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/authority/invites/{name}/cancel": {
      "post": {
        "description": "Cancel a device's invite before it is used.",
        "operationId": "cancel_invite_api_remote_authority_invites__name__cancel_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthorityResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Cancel Invite",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/conflicts": {
      "get": {
        "description": "Values that did not go in as made, with both sides.",
        "operationId": "conflicts_api_remote_conflicts_get",
        "parameters": [
          {
            "description": "open, resolved, or all.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "default": "open",
              "description": "open, resolved, or all.",
              "title": "Status"
            }
          },
          {
            "description": "Only conflicts about this record or thing.",
            "in": "query",
            "name": "record",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only conflicts about this record or thing.",
              "title": "Record"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ConflictResponse"
                  },
                  "title": "Response Conflicts Api Remote Conflicts Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Conflicts",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/conflicts/reopen": {
      "post": {
        "description": "Open conflicts again that were settled with `theirs` (an undo: that choice\nchanged nothing). Others are ignored; undo those from Activity.",
        "operationId": "reopen_api_remote_conflicts_reopen_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReopenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReopenResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Reopen",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/conflicts/resolve-many": {
      "post": {
        "description": "Settle every open conflict that matches (the given ids, kind and record; all\nof them if none is given) the same way, in one request. Conflicts that don't\noffer that way, or fail their checks, stay open and are counted or listed: the\nrest are still settled. `dry_run` only counts.",
        "operationId": "resolve_many_api_remote_conflicts_resolve_many_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolveManyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResolveManyResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Resolve Many",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/conflicts/{conflict_id}/resolve": {
      "post": {
        "description": "Settle a conflict. Putting a value back is an ordinary edit (checked, in the\nhistory, synced); it answers 409 with what is there now when the record's value\nchanged since the conflict was recorded, unless `force`.",
        "operationId": "resolve_api_remote_conflicts__conflict_id__resolve_post",
        "parameters": [
          {
            "in": "path",
            "name": "conflict_id",
            "required": true,
            "schema": {
              "title": "Conflict Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolveRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RemoteStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Resolve",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/connect": {
      "post": {
        "description": "Point this project at an authority. An empty project becomes a copy of\nit; a project with data fills an empty authority; two with data are refused.\n\nThe address, the invite and who holds data are checked before this answers\n(an invite is used up here: this computer joins the authority), so a\nmistake is said at once. Copying can take a long time, so it then runs in\nthe background: `GET /remote` says how far it has got (`progress`), and why\nit stopped if it did (`connect_error`).",
        "operationId": "connect_api_remote_connect_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RemoteConnectRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RemoteConnectResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Connect",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/disconnect": {
      "post": {
        "description": "Stop following the authority. The data here stays.",
        "operationId": "disconnect_api_remote_disconnect_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RemoteStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Disconnect",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/files": {
      "get": {
        "description": "Each collection's files on this computer: how many are here and their\nsize, how many are only on the server, and whether it keeps a copy here.",
        "operationId": "collection_files_api_remote_files_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/CollectionFilesResponse"
                  },
                  "title": "Response Collection Files Api Remote Files Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Collection Files",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/files/{collection}": {
      "patch": {
        "description": "Keep a collection's files on this computer, fetch them only when\nopened, or follow the project's setting. Keeping starts the background\ndownload of what is missing.",
        "operationId": "set_collection_mode_api_remote_files__collection__patch",
        "parameters": [
          {
            "in": "path",
            "name": "collection",
            "required": true,
            "schema": {
              "title": "Collection",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CollectionModeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/CollectionFilesResponse"
                  },
                  "title": "Response Set Collection Mode Api Remote Files  Collection  Patch",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Collection Mode",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/files/{collection}/free-up": {
      "post": {
        "description": "Remove this computer's copies of a collection's files to free space;\nthey are fetched again when opened. Only files the server confirms it\nholds, and never one a collection kept here also uses. Counts first unless\n`dry_run=false`, which also sets the collection to fetch when opened.",
        "operationId": "free_up_api_remote_files__collection__free_up_post",
        "parameters": [
          {
            "in": "path",
            "name": "collection",
            "required": true,
            "schema": {
              "title": "Collection",
              "type": "string"
            }
          },
          {
            "description": "Only count (the default).",
            "in": "query",
            "name": "dry_run",
            "required": false,
            "schema": {
              "default": true,
              "description": "Only count (the default).",
              "title": "Dry Run",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FreeUpResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Free Up",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/library": {
      "get": {
        "description": "The workflows and plugins shared through the authority (the newest\nversion of each, with its history), and where each stands here. Empty when\nthis project shares with no server.",
        "operationId": "library_api_remote_library_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/LibraryItemResponse"
                  },
                  "title": "Response Library Api Remote Library Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Library",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/library/publish": {
      "post": {
        "description": "Publish a workflow (with the plugins it uses, which it is pinned to) or\na plugin from this project to the library. New text is the next version.",
        "operationId": "publish_to_library_api_remote_library_publish_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/civex__server__routers__remote__LibraryPublishRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/civex__server__routers__remote__LibraryPublishResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Publish To Library",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/library/{kind}/{name}": {
      "delete": {
        "description": "Take something out of the library. Copies already installed stay.",
        "operationId": "unpublish_api_remote_library__kind___name__delete",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "description": "One version; omit to remove every version.",
            "in": "query",
            "name": "version",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "One version; omit to remove every version.",
              "title": "Version"
            }
          },
          {
            "description": "Even if shared workflows are pinned to it.",
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "default": false,
              "description": "Even if shared workflows are pinned to it.",
              "title": "Force",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Unpublish",
        "tags": [
          "sync"
        ]
      },
      "get": {
        "description": "One version of a shared workflow or plugin with its text, to read first.",
        "operationId": "library_item_api_remote_library__kind___name__get",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "description": "Omit for the newest.",
            "in": "query",
            "name": "version",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Omit for the newest.",
              "title": "Version"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LibraryItemResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Library Item",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/library/{kind}/{name}/install": {
      "get": {
        "description": "What installing (a version) would write here, what it would break among\nthe workflows here, and what stops it. Writes and runs nothing.",
        "operationId": "install_plan_api_remote_library__kind___name__install_get",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "version",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Version"
            }
          },
          {
            "in": "query",
            "name": "with_plugins",
            "required": false,
            "schema": {
              "default": true,
              "title": "With Plugins",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "replace",
            "required": false,
            "schema": {
              "default": false,
              "title": "Replace",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "default": false,
              "title": "Force",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstallPlanResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Install Plan",
        "tags": [
          "sync"
        ]
      },
      "post": {
        "description": "Install (a version) from the library into this project. A plugin is\ncode: it is described before anything is written, and runs on this\ncomputer from now on.",
        "operationId": "install_api_remote_library__kind___name__install_post",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LibraryInstallRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstallPlanResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Install",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/remote/sync": {
      "post": {
        "description": "Ask for a sync now. It runs in the background; `GET /remote` shows how it went.",
        "operationId": "sync_now_api_remote_sync_post",
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Sync Now",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/restore": {
      "post": {
        "description": "Restore schemas, datasets, records, and workflows from an uploaded YAML dump.",
        "operationId": "import_dump_api_restore_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_import_dump_api_restore_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestoreResult"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Import Dump",
        "tags": [
          "dump"
        ]
      }
    },
    "/api/retention/purged-history": {
      "post": {
        "description": "Delete the history of records that were permanently deleted before\npermanent deletes removed it themselves: every entry about a record that no\nlonger exists. Cannot be undone. With `dry_run` (the default) it only\ncounts.",
        "operationId": "forget_purged_api_retention_purged_history_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ForgetPurgedRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForgetPurgedResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Forget Purged",
        "tags": [
          "retention"
        ]
      }
    },
    "/api/retention/run": {
      "post": {
        "description": "Clean up by age: permanently delete items deleted before a date, remove\nchange history before a date, and remove finished workflow runs (with their\nstep logs) before a date. `from_settings` applies the retention settings;\na date given outright wins over the setting for that kind. With `dry_run`\n(the default) nothing is removed and the response says what would be.\n\nHistory about something that can still be restored is never removed. Files nothing\nrefers to afterwards are the file clean-up's job (`/store/gc`).",
        "operationId": "run_retention_api_retention_run_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RetentionRunRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RetentionReportResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Run Retention",
        "tags": [
          "retention"
        ]
      }
    },
    "/api/schemas": {
      "get": {
        "operationId": "list_schemas_api_schemas_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/SchemaResponse"
                  },
                  "title": "Response List Schemas Api Schemas Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Schemas",
        "tags": [
          "schemas"
        ]
      },
      "post": {
        "operationId": "create_schema_api_schemas_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSchemaRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Schema",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/deleted": {
      "get": {
        "description": "Schemas currently in Recently Deleted, most recently deleted first.",
        "operationId": "list_deleted_schemas_api_schemas_deleted_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/SchemaResponse"
                  },
                  "title": "Response List Deleted Schemas Api Schemas Deleted Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Deleted Schemas",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/field-types": {
      "get": {
        "description": "Every field type, the rules each can carry and how to present them,\nplus the field-kind picker. The web UI builds its field editor and its\nrecord-form guidance from this, so a new type or rule appears there\nwithout a frontend change.",
        "operationId": "field_types_api_schemas_field_types_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FieldTypesResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Field Types",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/lint": {
      "get": {
        "description": "Schema and field names that predate slug validation -- the same\nreport `civex schema lint` prints, exposed for the analytics\nnaming-health widget. Nothing is broken; these names still resolve.",
        "operationId": "lint_schema_names_api_schemas_lint_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/NameIssueResponse"
                  },
                  "title": "Response Lint Schema Names Api Schemas Lint Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Lint Schema Names",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name_or_id}": {
      "get": {
        "operationId": "get_schema_api_schemas__name_or_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "name_or_id",
            "required": true,
            "schema": {
              "title": "Name Or Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Schema",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}": {
      "delete": {
        "operationId": "delete_schema_api_schemas__name__delete",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Schema",
        "tags": [
          "schemas"
        ]
      },
      "patch": {
        "operationId": "update_schema_api_schemas__name__patch",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSchemaRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Schema",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/audit": {
      "get": {
        "description": "Audit entries for a schema and its own fields (not inherited ones),\nmost recent first \u2014 schema/field renames, field additions and removals,\nrestriction changes, and so on.",
        "operationId": "list_schema_audit_api_schemas__name__audit_get",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 1000,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "description": "Only entries of this action (create, update, ...).",
            "in": "query",
            "name": "action",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries of this action (create, update, ...).",
              "title": "Action"
            }
          },
          {
            "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "'timestamp' or 'action', optionally ':asc' / ':desc'. Newest first by default.",
              "title": "Sort"
            }
          },
          {
            "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries at or after this time (ISO 8601; a time with no zone is read as UTC).",
              "title": "Since"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedAuditLogResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Schema Audit",
        "tags": [
          "audit"
        ]
      }
    },
    "/api/schemas/{name}/delete-impact": {
      "get": {
        "description": "What deleting this schema would take with it, so the caller can warn\nbefore the delete happens rather than after it fails or silently loses data.",
        "operationId": "get_schema_delete_impact_api_schemas__name__delete_impact_get",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaDeleteImpactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Schema Delete Impact",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/fields": {
      "post": {
        "operationId": "add_field_api_schemas__name__fields_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddFieldRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FieldResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Add Field",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/fields/reorder": {
      "put": {
        "operationId": "reorder_fields_api_schemas__name__fields_reorder_put",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReorderFieldsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Reorder Fields",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/fields/{field_id}/restore": {
      "post": {
        "description": "Bring a deleted field back, with every value records still hold for it.",
        "operationId": "restore_field_api_schemas__name__fields__field_id__restore_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "field_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Field Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FieldResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Field",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/fields/{field_id}/restore-plan": {
      "get": {
        "description": "What restoring a deleted field would do: it returns to the schema with\nthe values records still hold for it. Blocked while the schema is deleted,\nor when a live field has since taken its name.",
        "operationId": "restore_field_plan_api_schemas__name__fields__field_id__restore_plan_get",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "field_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Field Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestorePlanResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Field Plan",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/fields/{field_name}": {
      "delete": {
        "operationId": "delete_field_api_schemas__name__fields__field_name__delete",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "field_name",
            "required": true,
            "schema": {
              "title": "Field Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Field",
        "tags": [
          "schemas"
        ]
      },
      "patch": {
        "operationId": "update_field_api_schemas__name__fields__field_name__patch",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "field_name",
            "required": true,
            "schema": {
              "title": "Field Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateFieldRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FieldResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Field",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/preview-name": {
      "post": {
        "description": "Render a name template against sample values without saving it. An\ninvalid template is answered with `error` set, not an HTTP error, so an\neditor can show the problem as the person types.",
        "operationId": "preview_name_api_schemas__name__preview_name_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewNameRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreviewNameResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Preview Name",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/purge": {
      "delete": {
        "operationId": "purge_schema_api_schemas__name__purge_delete",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Purge Schema",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/restore": {
      "post": {
        "operationId": "restore_schema_api_schemas__name__restore_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Schema",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/restore-plan": {
      "get": {
        "description": "What restoring a deleted schema would bring back: it and the records\ndeleted with it, not records deleted on their own earlier.",
        "operationId": "restore_schema_plan_api_schemas__name__restore_plan_get",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestorePlanResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Schema Plan",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{name}/unique-keys": {
      "put": {
        "description": "Replace a schema's uniqueness policies.\n\nEach key is a set of the schema's own fields that no two records may\nshare the values of, within the same parent record (top-level records:\nthe same collection). Refused with 422 when existing records already\nbreak a key being added. Records with a blank in a key's fields are not\nconstrained by it.",
        "operationId": "set_unique_keys_api_schemas__name__unique_keys_put",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetUniqueKeysRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchemaResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Unique Keys",
        "tags": [
          "schemas"
        ]
      }
    },
    "/api/schemas/{schema_name}/exports": {
      "get": {
        "description": "The exports saved with a schema.",
        "operationId": "list_exports_api_schemas__schema_name__exports_get",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ExportDefinitionResponse"
                  },
                  "title": "Response List Exports Api Schemas  Schema Name  Exports Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Exports",
        "tags": [
          "exports"
        ]
      },
      "post": {
        "description": "Save an export with a schema: the kind of record that holds the files, which\nfile fields, an optional filter, and a layout. It is then offered on\ncollections that use the schema and on records of it and of the schemas below\nit, down to the kind that holds the files. Checked as a whole: the holder must\nbe the schema or beneath it, and the fields must be file fields it has.",
        "operationId": "create_export_api_schemas__schema_name__exports_post",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExportDefinitionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportDefinitionResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Export",
        "tags": [
          "exports"
        ]
      }
    },
    "/api/schemas/{schema_name}/exports/{export_name}": {
      "delete": {
        "description": "Delete a saved export. Folders it already made are left (they are listed\nunder /file-access/exports).",
        "operationId": "delete_export_api_schemas__schema_name__exports__export_name__delete",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "export_name",
            "required": true,
            "schema": {
              "title": "Export Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Export",
        "tags": [
          "exports"
        ]
      },
      "get": {
        "description": "One saved export.",
        "operationId": "get_export_api_schemas__schema_name__exports__export_name__get",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "export_name",
            "required": true,
            "schema": {
              "title": "Export Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportDefinitionResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Export",
        "tags": [
          "exports"
        ]
      },
      "patch": {
        "description": "Change a saved export. A key left out is left alone; `holder` and\n`filter_tree` may be sent as null to clear them. The result is checked as a\nwhole.",
        "operationId": "update_export_api_schemas__schema_name__exports__export_name__patch",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "export_name",
            "required": true,
            "schema": {
              "title": "Export Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateExportDefinitionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportDefinitionResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Export",
        "tags": [
          "exports"
        ]
      }
    },
    "/api/schemas/{schema_name}/records": {
      "get": {
        "description": "List a schema's records across every collection -- the same query as\na collection's list, just not scoped to one collection (what a saved view\nbrowses).",
        "operationId": "list_schema_records_api_schemas__schema_name__records_get",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          },
          {
            "description": "Repeatable column names whose values aren't in a record's own 'data' -- inherited fields and 'ref_field.target_field' joins -- returned under each record's 'derived'.",
            "in": "query",
            "name": "columns",
            "required": false,
            "schema": {
              "default": [],
              "description": "Repeatable column names whose values aren't in a record's own 'data' -- inherited fields and 'ref_field.target_field' joins -- returned under each record's 'derived'.",
              "items": {
                "type": "string"
              },
              "title": "Columns",
              "type": "array"
            }
          },
          {
            "description": "Attach each record's live child count per child schema.",
            "in": "query",
            "name": "child_counts",
            "required": false,
            "schema": {
              "default": false,
              "description": "Attach each record's live child count per child schema.",
              "title": "Child Counts",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 1000,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "description": "Only records of this schema.",
            "in": "query",
            "name": "schema",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only records of this schema.",
              "title": "Schema"
            }
          },
          {
            "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
            "in": "query",
            "name": "within",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): only records of 'schema' that descend from it, at any depth -- an encounter's selections, not just its recordings. Requires 'schema'.",
              "title": "Within"
            }
          },
          {
            "description": "Record id (or prefix): direct children only, of any schema.",
            "in": "query",
            "name": "parent_record_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Record id (or prefix): direct children only, of any schema.",
              "title": "Parent Record Id"
            }
          },
          {
            "description": "Full-text search across all field values",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Full-text search across all field values",
              "title": "Search"
            }
          },
          {
            "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
            "in": "query",
            "name": "where",
            "required": false,
            "schema": {
              "default": [],
              "description": "Simple equality filter, repeatable: 'field=value'. AND-combined with each other and with 'filter'. Kept for backwards compatibility -- prefer 'filter' for anything beyond plain equality.",
              "items": {
                "type": "string"
              },
              "title": "Where",
              "type": "array"
            }
          },
          {
            "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
            "in": "query",
            "name": "filter",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "JSON-encoded filter tree, AND/OR groups of field conditions. Leaf: {\"field\": \"<name>\", \"op\": \"eq\"|\"ne\"|\"gt\"|\"gte\"|\"lt\"|\"lte\"|\"contains\"|\"in\"|\"is_null\", \"value\": ..., \"schema\": \"<name>\"?}. Group: {\"and\": [<node>, ...]} or {\"or\": [<node>, ...]}, nestable. 'value' must be a list for 'in' and is optional (default true) for 'is_null'. A leaf tests the listed schema's own field unless it names another 'schema': an ancestor's (tests the parent/grandparent record) or a descendant's (matches records having ANY such descendant that satisfies it). An inherited field name resolves to the ancestor that owns it. Example: {\"and\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}, {\"schema\": \"selection\", \"field\": \"selection_table\", \"op\": \"is_null\"}]}",
              "title": "Filter"
            }
          },
          {
            "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": [],
              "description": "Repeatable '[schema.]field[:asc|desc]'. Nulls sort last either way. Needs 'schema'; 'schema.' names an ancestor whose field to sort by.",
              "items": {
                "type": "string"
              },
              "title": "Sort",
              "type": "array"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedRecordResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Schema Records",
        "tags": [
          "records"
        ]
      }
    },
    "/api/schemas/{schema_name}/views": {
      "get": {
        "description": "Saved views for a single schema.",
        "operationId": "list_views_api_schemas__schema_name__views_get",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ViewResponse"
                  },
                  "title": "Response List Views Api Schemas  Schema Name  Views Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Views",
        "tags": [
          "views"
        ]
      },
      "post": {
        "description": "Create a saved column/filter/sort view against a schema's own fields,\nwith columns optionally joining one hop through a reference field.\n`files_layout` says how its files are arranged when it is exported as a\nfolder or zip.",
        "operationId": "create_view_api_schemas__schema_name__views_post",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateViewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ViewResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create View",
        "tags": [
          "views"
        ]
      }
    },
    "/api/schemas/{schema_name}/views/preview": {
      "post": {
        "description": "Rows + total count for a column/filter/sort selection without saving\nit as a view -- backs the view builder's live preview.",
        "operationId": "preview_view_api_schemas__schema_name__views_preview_post",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewViewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreviewViewResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Preview View",
        "tags": [
          "views"
        ]
      }
    },
    "/api/schemas/{schema_name}/views/{view_name}": {
      "delete": {
        "description": "Delete a saved view. Does not affect the underlying records.",
        "operationId": "delete_view_api_schemas__schema_name__views__view_name__delete",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "view_name",
            "required": true,
            "schema": {
              "title": "View Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete View",
        "tags": [
          "views"
        ]
      },
      "get": {
        "description": "A single saved view by name.",
        "operationId": "get_view_api_schemas__schema_name__views__view_name__get",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "view_name",
            "required": true,
            "schema": {
              "title": "View Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ViewResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get View",
        "tags": [
          "views"
        ]
      },
      "patch": {
        "description": "Rename a view and/or replace its columns/filter_tree/sort/files_layout.",
        "operationId": "update_view_api_schemas__schema_name__views__view_name__patch",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "view_name",
            "required": true,
            "schema": {
              "title": "View Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateViewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ViewResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update View",
        "tags": [
          "views"
        ]
      }
    },
    "/api/schemas/{schema_name}/views/{view_name}/export": {
      "get": {
        "description": "Export a view's rows as csv, tsv, xlsx, json or jsonl, honoring its saved\nfilter and sort and flattening `columns` (joined columns are dotted headers\n\"ref_field.target_field\" in the text formats; json nests them). Any\nfile/file_list column gets bundled into a zip alongside the table, laid out as\nthe view's `files_layout` says -- the same paths as the Files menu -- and each\nfile cell holds that path. Files that can't be reached (a drive that isn't\nconnected) are left out and listed in MISSING.txt. This is the same export as\nPOST /file-access/zip with `view`, which also takes a collection or record to\nrun it in.",
        "operationId": "export_view_api_schemas__schema_name__views__view_name__export_get",
        "parameters": [
          {
            "in": "path",
            "name": "schema_name",
            "required": true,
            "schema": {
              "title": "Schema Name",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "view_name",
            "required": true,
            "schema": {
              "title": "View Name",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "default": "csv",
              "pattern": "^(csv|tsv|xlsx|json|jsonl)$",
              "title": "Format",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Export View",
        "tags": [
          "views"
        ]
      }
    },
    "/api/settings/command-line": {
      "delete": {
        "description": "Take the desktop app's `civex` off PATH again (only ever its own entry\nor link).",
        "operationId": "remove_command_line_api_settings_command_line_delete",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandLineResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Remove Command Line",
        "tags": [
          "settings"
        ]
      },
      "get": {
        "description": "Whether the desktop app's `civex` can be typed in a terminal.",
        "operationId": "get_command_line_api_settings_command_line_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandLineResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Command Line",
        "tags": [
          "settings"
        ]
      },
      "post": {
        "description": "Put the desktop app's `civex` on PATH: the user PATH on Windows (no\nadministrator), a link in ~/.local/bin on macOS and Linux. 409 when this\nisn't the desktop app's civex, or the link's place is taken.",
        "operationId": "add_command_line_api_settings_command_line_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandLineResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Add Command Line",
        "tags": [
          "settings"
        ]
      }
    },
    "/api/settings/identity": {
      "get": {
        "description": "Who changes made in this project are recorded as.",
        "operationId": "get_identity_api_settings_identity_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdentityResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Identity",
        "tags": [
          "settings"
        ]
      },
      "patch": {
        "description": "Choose the name recorded on changes made in this project. It is saved\nin this project's config.toml.",
        "operationId": "update_identity_api_settings_identity_patch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateIdentityRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdentityResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Identity",
        "tags": [
          "settings"
        ]
      }
    },
    "/api/settings/map": {
      "get": {
        "description": "Where the location editor gets street-level map tiles, if anywhere.",
        "operationId": "get_map_settings_api_settings_map_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MapSettingsResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Map Settings",
        "tags": [
          "settings"
        ]
      },
      "patch": {
        "description": "Set (or clear, with null) the map tile URL. It must be an http(s) XYZ\nURL containing {z}, {x} and {y}. The provider's terms of use apply.",
        "operationId": "update_map_settings_api_settings_map_patch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMapSettingsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MapSettingsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Map Settings",
        "tags": [
          "settings"
        ]
      }
    },
    "/api/settings/retention": {
      "get": {
        "description": "Return how long this project keeps deleted items, change history and\nworkflow runs. Nothing is removed by itself: a clean-up applies these.",
        "operationId": "get_retention_settings_api_settings_retention_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RetentionSettingsResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Retention Settings",
        "tags": [
          "settings"
        ]
      },
      "patch": {
        "description": "Change the retention settings. Only the fields sent change; a null\n`audit_days` or `run_days` means keep that kind forever.",
        "operationId": "update_retention_settings_api_settings_retention_patch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRetentionSettingsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RetentionSettingsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Retention Settings",
        "tags": [
          "settings"
        ]
      }
    },
    "/api/settings/shortcut": {
      "get": {
        "description": "Whether this project has a Desktop shortcut that starts civex.",
        "operationId": "get_shortcut_api_settings_shortcut_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShortcutResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Shortcut",
        "tags": [
          "settings"
        ]
      },
      "post": {
        "description": "Put a Desktop shortcut that starts civex for this project and opens it\nin the browser. Runs on the machine civex runs on.",
        "operationId": "create_shortcut_api_settings_shortcut_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShortcutResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Create Shortcut",
        "tags": [
          "settings"
        ]
      }
    },
    "/api/settings/ui": {
      "get": {
        "description": "Return this project's UI preferences.",
        "operationId": "get_ui_settings_api_settings_ui_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UISettingsResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Ui Settings",
        "tags": [
          "settings"
        ]
      },
      "patch": {
        "description": "Update this project's UI preferences.",
        "operationId": "update_ui_settings_api_settings_ui_patch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUISettingsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UISettingsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Ui Settings",
        "tags": [
          "settings"
        ]
      }
    },
    "/api/status/db": {
      "get": {
        "description": "Tests the database connection with a live round-trip. A bare\nDepends(get_ctx) isn't enough on its own \u2014 SQLAlchemy Sessions connect\nlazily, so building the context doesn't prove a query would actually\nsucceed. A failure here is caught by get_ctx() the same as any other\nroute's query (auto-recovers a docker-managed container when possible).",
        "operationId": "db_status_api_status_db_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DBStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Db Status",
        "tags": [
          "status"
        ]
      }
    },
    "/api/store/browse": {
      "get": {
        "description": "List the folders inside a directory on the machine running Civex, for\nchoosing where a volume lives.\n\nFolders only, never files. Starts at the home folder when `path` is omitted,\nand also returns places to start from: the project, home and mounted drives\n(network drives marked as such). A location that doesn't answer in a few\nseconds is reported as not responding rather than waited on.",
        "operationId": "browse_directory_api_store_browse_get",
        "parameters": [
          {
            "in": "query",
            "name": "path",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Path"
            }
          },
          {
            "in": "query",
            "name": "show_hidden",
            "required": false,
            "schema": {
              "default": false,
              "title": "Show Hidden",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DirectoryListingResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Browse Directory",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/browse/folder": {
      "post": {
        "description": "Create a folder while choosing a volume location.",
        "operationId": "create_folder_api_store_browse_folder_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFolderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateFolderResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Folder",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/collections": {
      "get": {
        "description": "Where every collection's files are stored, in one call.\n\nThe same answer as `GET /store/collections/{id}` for each collection that\nhas files, for pages that show them side by side. Collections with no files\nare left out.",
        "operationId": "all_collection_storage_api_store_collections_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/CollectionStorageResponse"
                  },
                  "title": "Response All Collection Storage Api Store Collections Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "All Collection Storage",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/collections/{collection_id}": {
      "get": {
        "description": "Where a collection's files are stored.\n\nLists each volume that holds some of the collection's files, with how many\nfiles and bytes, how many of those another collection also uses, and whether\nthe volume can be read now. Answered from the catalog, so it is quick however\nmany files there are.",
        "operationId": "collection_storage_api_store_collections__collection_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "collection_id",
            "required": true,
            "schema": {
              "title": "Collection Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionStorageResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Collection Storage",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/gc": {
      "post": {
        "description": "Reclaim object-store blobs no longer referenced by any live record or\nworkflow job. Defaults to a dry run (`apply=false`) that only reports\nwhat's collectible; pass `apply=true` to actually delete. Objects\nreferenced only by audit history or job step logs are not protected --\nboth retain FileRef snapshots indefinitely, so an old audit diff may\nreference a hash GC has since removed. Pass `volume` to clean up one\nvolume only (404 if there is no such volume).",
        "operationId": "run_gc_api_store_gc_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GCRequest",
                "default": {
                  "apply": false,
                  "grace_days": 14,
                  "rebuild_refs": false
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GCReportResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Run Gc",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/inspect": {
      "get": {
        "description": "What adding a folder as a volume would involve, before doing it.\n\nReports whether it exists or would be created, whether Civex can write to\nit, free space, whether it is on a network drive or on the same disk as the\nproject, and whether it is already a volume or carries another volume's\nidentity. `problems` are reasons adding it would be refused; `warnings` are\nthings worth knowing. Adding a volume enforces exactly these rules.",
        "operationId": "inspect_path_api_store_inspect_get",
        "parameters": [
          {
            "in": "query",
            "name": "path",
            "required": true,
            "schema": {
              "title": "Path",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PathInspectionResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Inspect Path",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/placement": {
      "get": {
        "description": "Every collection that has a home volume.\n\nA placement only steers where a collection's *new* files are written. A file\nwhose content already exists on any volume is reused where it lives and is\nnever copied again.",
        "operationId": "list_placements_api_store_placement_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/PlacementResponse"
                  },
                  "title": "Response List Placements Api Store Placement Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Placements",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/placement/{collection_id}": {
      "delete": {
        "description": "Send a collection's new files back to the general write queue.",
        "operationId": "clear_placement_api_store_placement__collection_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "collection_id",
            "required": true,
            "schema": {
              "title": "Collection Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Clear Placement",
        "tags": [
          "store"
        ]
      },
      "put": {
        "description": "Make a volume the home of a collection's new files.\n\nThe collection is identified by id, so renaming it changes nothing here. The\nhome need not be in the general write queue.",
        "operationId": "set_placement_api_store_placement__collection_id__put",
        "parameters": [
          {
            "in": "path",
            "name": "collection_id",
            "required": true,
            "schema": {
              "title": "Collection Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetPlacementRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlacementResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Placement",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/queue": {
      "put": {
        "operationId": "set_queue_api_store_queue_put",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetQueueRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "type": "string"
                  },
                  "title": "Response Set Queue Api Store Queue Put",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Queue",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/transfers": {
      "get": {
        "description": "Past and running transfers, newest first.",
        "operationId": "list_transfers_api_store_transfers_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/TransferResponse"
                  },
                  "title": "Response List Transfers Api Store Transfers Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Transfers",
        "tags": [
          "store"
        ]
      },
      "post": {
        "description": "Queue a move of files between volumes. Moves run one at a time, in the\norder they were queued, so asking for a second while one is running is fine:\nit waits its turn (`status` is `queued`).\n\nPoll `GET /store/transfers/{id}` for progress. A file is only removed from\nits source after the copy has been checked and recorded, so a transfer can\nbe paused, cancelled, interrupted or lose power at any moment without losing\nanything. Refused (422) with every reason if it can't start.",
        "operationId": "start_transfer_api_store_transfers_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransferRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransferResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Start Transfer",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/transfers/preview": {
      "post": {
        "description": "What a transfer would do, without doing anything.\n\nReports how many files and bytes would move and where each target would put\nthem, and lists `problems` that would stop it (a volume that is offline or\nread-only, not enough room) and `warnings` that\nare worth knowing. The sizes come from the catalog, so they are close, not\nexact.",
        "operationId": "preview_transfer_api_store_transfers_preview_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransferRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransferPlanResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Preview Transfer",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/transfers/{transfer_id}": {
      "get": {
        "description": "A transfer's progress and outcome: files and bytes done, speed and time\nremaining, the file being copied, anything that couldn't be moved, and why\nit is paused if it is. A running transfer that has stopped saving progress\n(its process died) is reported as `interrupted`.",
        "operationId": "get_transfer_api_store_transfers__transfer_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "transfer_id",
            "required": true,
            "schema": {
              "title": "Transfer Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransferResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Transfer",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/transfers/{transfer_id}/cancel": {
      "post": {
        "description": "Stop a transfer for good. Nothing already moved is moved back and no file\nis lost; volumes it made read-only are restored.",
        "operationId": "cancel_transfer_api_store_transfers__transfer_id__cancel_post",
        "parameters": [
          {
            "in": "path",
            "name": "transfer_id",
            "required": true,
            "schema": {
              "title": "Transfer Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransferResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Cancel Transfer",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/transfers/{transfer_id}/pause": {
      "post": {
        "description": "Ask a transfer to pause. A running one stops within a moment, discarding\nany half-copied file, and keeps everything already moved; a queued one is\ntaken out of the queue. Works for a transfer started from the command line\nas well as one running here.",
        "operationId": "pause_transfer_api_store_transfers__transfer_id__pause_post",
        "parameters": [
          {
            "in": "path",
            "name": "transfer_id",
            "required": true,
            "schema": {
              "title": "Transfer Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransferResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Pause Transfer",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/transfers/{transfer_id}/resume": {
      "post": {
        "description": "Put a paused, failed or interrupted transfer back in the queue; it carries\non where it left off when its turn comes. What is already moved is not moved\nagain.",
        "operationId": "resume_transfer_api_store_transfers__transfer_id__resume_post",
        "parameters": [
          {
            "in": "path",
            "name": "transfer_id",
            "required": true,
            "schema": {
              "title": "Transfer Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransferResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Resume Transfer",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/volumes": {
      "get": {
        "description": "Every volume with its state and usage, including how much of what it\nholds no collection uses (`unused_*`, which garbage collection can reclaim,\nand `history_*`, kept only for workflow run history).",
        "operationId": "list_volumes_api_store_volumes_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/VolumeStatsResponse"
                  },
                  "title": "Response List Volumes Api Store Volumes Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Volumes",
        "tags": [
          "store"
        ]
      },
      "post": {
        "operationId": "add_volume_api_store_volumes_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddVolumeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumeStatsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Add Volume",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/volumes/{name}": {
      "delete": {
        "operationId": "remove_volume_api_store_volumes__name__delete",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "default": false,
              "title": "Force",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Remove Volume",
        "tags": [
          "store"
        ]
      },
      "patch": {
        "operationId": "update_volume_api_store_volumes__name__patch",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateVolumeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumeStatsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Volume",
        "tags": [
          "store"
        ]
      }
    },
    "/api/store/volumes/{name}/adopt": {
      "post": {
        "description": "Declare that the drive at the volume's path is that volume.\n\nVolumes are recognised by an identity marker in their root, so civex can\ntell an unplugged drive from a different drive mounted at the same path.\nUse this when a volume is reported as `wrong_drive` but the drive is in fact\nthe right one (the marker was deleted, or the drive was re-formatted): it\nrewrites the marker. Nothing else on the drive is changed.",
        "operationId": "adopt_volume_api_store_volumes__name__adopt_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VolumeStatsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Adopt Volume",
        "tags": [
          "store"
        ]
      }
    },
    "/api/sync/v1/feed": {
      "get": {
        "description": "Everyone's changes past `after`, in the order the authority numbered them.",
        "operationId": "feed_api_sync_v1_feed_get",
        "parameters": [
          {
            "description": "The last number the device has.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "default": 0,
              "description": "The last number the device has.",
              "minimum": 0,
              "title": "After",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 200,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncFeedResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Feed",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/sync/v1/files/missing": {
      "post": {
        "description": "Which of these files the authority does not have: what a device uploads\nbefore the changes that cite them.",
        "operationId": "files_missing_api_sync_v1_files_missing_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncFilesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncFilesResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Files Missing",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/sync/v1/files/{sha256}": {
      "get": {
        "description": "The bytes of a file the authority holds, for a device that was sent only\nthe record that cites it.",
        "operationId": "download_file_api_sync_v1_files__sha256__get",
        "parameters": [
          {
            "in": "path",
            "name": "sha256",
            "required": true,
            "schema": {
              "title": "Sha256",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Download File",
        "tags": [
          "sync"
        ]
      },
      "put": {
        "description": "Store a file under its content hash. The bytes are hashed as they arrive;\nones that don't match `sha256` are refused.",
        "operationId": "upload_file_api_sync_v1_files__sha256__put",
        "parameters": [
          {
            "in": "path",
            "name": "sha256",
            "required": true,
            "schema": {
              "title": "Sha256",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Upload File",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/sync/v1/hello": {
      "get": {
        "description": "Say who this server is: its project, its latest number, whether it holds\ndata. A device asks first, to decide whether to join, fill it, or stop.",
        "operationId": "hello_api_sync_v1_hello_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncHelloResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Hello",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/sync/v1/join": {
      "post": {
        "description": "Join with an invite: the device's public key is kept, the invite is\nused up, and the answer carries the authority's key.",
        "operationId": "join_api_sync_v1_join_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncJoinRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncJoinResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Join",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/sync/v1/library": {
      "get": {
        "description": "The workflows and plugins shared through this server: the newest version\nof each, with its history, without its text.",
        "operationId": "library_api_sync_v1_library_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LibraryListResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Library",
        "tags": [
          "sync"
        ]
      },
      "post": {
        "description": "Publish to the library. Refused (403) unless the admin allowed this\ndevice, and for plugins unless the server takes them; checked without being\nrun, and taken whole or not at all. A workflow is pinned to the plugin\nversions it is published with.",
        "operationId": "publish_api_sync_v1_library_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/civex__server__routers__sync_peer__LibraryPublishRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/civex__server__routers__sync_peer__LibraryPublishResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Publish",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/sync/v1/library/{kind}/{name}": {
      "delete": {
        "description": "Take something out of the library. Copies already installed stay.",
        "operationId": "unpublish_api_sync_v1_library__kind___name__delete",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "description": "One version; omit to remove every version.",
            "in": "query",
            "name": "version",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "One version; omit to remove every version.",
              "title": "Version"
            }
          },
          {
            "description": "Remove a plugin version even if shared workflows are pinned to it.",
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "default": false,
              "description": "Remove a plugin version even if shared workflows are pinned to it.",
              "title": "Force",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Unpublish",
        "tags": [
          "sync"
        ]
      },
      "get": {
        "description": "One version of a shared workflow or plugin, with its text.",
        "operationId": "library_item_api_sync_v1_library__kind___name__get",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          },
          {
            "description": "Omit for the newest.",
            "in": "query",
            "name": "version",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Omit for the newest.",
              "title": "Version"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Library Item Api Sync V1 Library  Kind   Name  Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Library Item",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/sync/v1/push": {
      "post": {
        "description": "Settle the changes a device made. Each is merged with what the authority\nholds, numbered, and answered; the answer is remembered, so a repeat (the\ndevice never heard) is answered the same way and nothing is done twice.",
        "operationId": "push_api_sync_v1_push_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncPushRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncPushResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Push",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/sync/v1/session": {
      "post": {
        "description": "Sign in: a request signed with the device's key, for a token that\nexpires in minutes.",
        "operationId": "session_api_sync_v1_session_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncSessionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncSessionResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Session",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/sync/v1/snapshot/{kind}": {
      "get": {
        "description": "One kind of thing as it is now, a page at a time, for a device joining\nthe project: schema, field, dataset, view, record (in that order).",
        "operationId": "snapshot_api_sync_v1_snapshot__kind__get",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          },
          {
            "description": "The previous page's `next`; omit for the first.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The previous page's `next`; omit for the first.",
              "title": "After"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 200,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncSnapshotResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Snapshot",
        "tags": [
          "sync"
        ]
      }
    },
    "/api/update": {
      "get": {
        "description": "Whether a newer civex is available, and whether this copy can install it\nfrom the app (the same check as `civex update --check`).",
        "operationId": "update_status_api_update_get",
        "parameters": [
          {
            "description": "Look for pre-releases too.",
            "in": "query",
            "name": "pre",
            "required": false,
            "schema": {
              "default": false,
              "description": "Look for pre-releases too.",
              "title": "Pre",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Status",
        "tags": [
          "update"
        ]
      },
      "post": {
        "description": "Update civex and start it again. civex closes once this answers; the\nupdate runs after it has exited (a running copy can't be replaced on\nWindows), and its outcome is in `last` on the next status. 409 when this\ncopy can't be updated from the app (`blocked` says why).",
        "operationId": "start_update_api_update_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartUpdateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartUpdateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Start Update",
        "tags": [
          "update"
        ]
      }
    },
    "/api/views": {
      "get": {
        "description": "Every saved view across every schema, sorted by schema then view\nname -- backs the top-level Views index page.",
        "operationId": "list_all_views_api_views_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ViewResponse"
                  },
                  "title": "Response List All Views Api Views Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List All Views",
        "tags": [
          "views"
        ]
      }
    },
    "/api/workflows": {
      "get": {
        "operationId": "list_workflows_api_workflows_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/WorkflowResponse"
                  },
                  "title": "Response List Workflows Api Workflows Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Workflows",
        "tags": [
          "workflows"
        ]
      }
    },
    "/api/workflows/{name}/run": {
      "post": {
        "operationId": "run_workflow_api_workflows__name__run_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowJobResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Run Workflow",
        "tags": [
          "workflows"
        ]
      }
    },
    "/api/workflows/{name}/run-many": {
      "post": {
        "description": "Run one workflow on several records: one queued run per record, in one\nrequest, one commit and one pass of the worker. A record that is missing, or\nis not the schema the workflow is for, is listed under `skipped` with the\nreason and the rest are still queued. A workflow that asks for files cannot\nbe run this way (422): the files differ per run. Refused (422) while\nautomation is paused.",
        "operationId": "run_workflow_on_many_api_workflows__name__run_many_post",
        "parameters": [
          {
            "in": "path",
            "name": "name",
            "required": true,
            "schema": {
              "title": "Name",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunManyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunManyResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Run Workflow On Many",
        "tags": [
          "workflows"
        ]
      }
    },
    "/api/workflows/{stem}": {
      "delete": {
        "operationId": "delete_workflow_api_workflows__stem__delete",
        "parameters": [
          {
            "in": "path",
            "name": "stem",
            "required": true,
            "schema": {
              "title": "Stem",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "default": false,
              "title": "Force",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Workflow",
        "tags": [
          "workflows"
        ]
      },
      "get": {
        "operationId": "get_workflow_api_workflows__stem__get",
        "parameters": [
          {
            "in": "path",
            "name": "stem",
            "required": true,
            "schema": {
              "title": "Stem",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowDetailResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Workflow",
        "tags": [
          "workflows"
        ]
      },
      "put": {
        "operationId": "save_workflow_api_workflows__stem__put",
        "parameters": [
          {
            "in": "path",
            "name": "stem",
            "required": true,
            "schema": {
              "title": "Stem",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkflowSaveRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowDetailResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Save Workflow",
        "tags": [
          "workflows"
        ]
      }
    }
  },
  "tags": [
    {
      "description": "What an authority offers to the devices that follow it: handshake, push, feed, snapshot and files. For other civex installs, not people; only reachable remotely on an instance set to serve.",
      "name": "sync"
    },
    {
      "description": "Define the shape of your data: schemas are named collections of typed fields (integer, float, string, boolean, date, datetime, file, file_list, reference), with restrictions (min/max, choices, accepted file types, ...) and optional inheritance from a parent schema. Create a schema before creating any records.",
      "name": "schemas"
    },
    {
      "description": "Datasets are named containers of records that all conform to the same schema. Use this to create, rename, or delete the datasets you organize records into.",
      "name": "collections"
    },
    {
      "description": "Create, read, update, delete, and bulk-import the individual rows of data that live inside a dataset. Record data is validated against its schema's field types and restrictions on every write.",
      "name": "records"
    },
    {
      "description": "Upload binary attachments (referenced from `file` / `file_list` record fields) and download them back out by content hash.",
      "name": "files"
    },
    {
      "description": "Author and manage YAML workflow definitions: chains of plugin steps, triggered automatically on record create/update or run manually, that read and write record fields.",
      "name": "workflows"
    },
    {
      "description": "Inspect the queue of workflow runs \u2014 one job per trigger firing or manual run \u2014 including their status, inputs, and outputs.",
      "name": "jobs"
    },
    {
      "description": "Read the change history recorded for records, schemas, fields, and datasets \u2014 every create/update/delete with a full before/after data snapshot and timestamp.",
      "name": "audit"
    },
    {
      "description": "Clean up by age: deleted items, change history and finished workflow runs older than the retention settings or a given date.",
      "name": "retention"
    },
    {
      "description": "Discover the built-in and project-defined plugins available to use as workflow steps, along with their declared inputs and outputs. Also handles uploading container-tier (Tier 2) plugins.",
      "name": "plugins"
    },
    {
      "description": "AI-assisted helpers layered on top of the data model \u2014 schema suggestions, record extraction, and similar model-backed endpoints \u2014 plus the AI provider configuration they run against.",
      "name": "ai"
    },
    {
      "description": "Push and pull a project's schemas, datasets, and records to/from a remote civex server, and check the current sync status.",
      "name": "remote"
    },
    {
      "description": "Manage the object volumes that back file storage \u2014 add, update, or remove a volume, and inspect per-volume usage stats.",
      "name": "store"
    },
    {
      "description": "Inspect and configure the underlying database connection: connection status, pending migrations, the configured URL, and (when using the bundled Docker Postgres) container lifecycle. Deliberately reachable even when the database itself is down.",
      "name": "db"
    },
    {
      "description": "Export a full project (schemas, datasets, records) to a single portable archive, and restore a project from one \u2014 the basis for backups and moving a project between machines.",
      "name": "dump"
    },
    {
      "description": "Read-only endpoints for the software's own license text and acceptable-use policy, independent of any particular project.",
      "name": "legal"
    },
    {
      "description": "Live health checks, such as a round-trip database query, for monitoring whether a running server is actually functional.",
      "name": "status"
    },
    {
      "description": "A WebSocket-backed interactive shell in the project directory, used by the web UI's embedded terminal panel.",
      "name": "terminal"
    },
    {
      "description": "Updating civex itself from the app: whether a newer version is on PyPI, and updating and starting again. The update runs after civex has exited, so a running copy is never replaced.",
      "name": "update"
    },
    {
      "description": "Per-project UI preferences, such as whether the Advanced navigation section (terminal, YAML editing, plugin editors) is shown by default.",
      "name": "settings"
    },
    {
      "description": "Aggregate, filterable, time-bucketed reads over records, workflow jobs, audit events, and AI usage \u2014 the read path dashboard widgets call. Every endpoint shares one query-param filter contract (date range, dataset, schema, workflow_id, plugin_id, status, trigger); each documents which of those it actually applies.",
      "name": "analytics"
    }
  ]
}