{
    "openapi": "3.0.0",
    "info": {
        "title": "SKYDB API",
        "description": "SKYDB is a reference database for tall buildings worldwide. It covers every\nstructure across its full life cycle, from first proposal through under\nconstruction, completed, altered and demolished. Records are built from primary sources\n(blueprints, building permits, developer filings, on-site photography), every\nvalue carries who set it, when, and from which source, and disputed values are\nkept alongside the accepted one rather than silently overwritten.\n\nThis API exposes the dataset. It currently contains **1.1 M structures**, including\n**224 k tall buildings**, across **210 k regions**, plus **60 k companies** and a\n**780 k-file media archive**, through the same JSON endpoints that power\nwww.skydb.net. Typical uses: looking up a building and its technical data,\nresolving a place to its structures, filtered and geo-radius search, map viewport\nqueries, and reading the companies attached to a project.\n\n## Access levels\n\nNot every endpoint is open. Access comes in three levels, and each operation\nbelow states which one it needs:\n\n- **Public**: no account. Single-record lookups, page one of any list, map\n  viewport queries. Enough to build a link, a preview or an embed.\n- **Member**: a free SKYDB account, signed in. Required to page beyond the\n  first page of a result set, to run statistics, and for everything that writes:\n  adding or editing a structure, uploading a photo, rating, contributing.\n- **Paid plan**: a SKYDB Insights subscription or an editorial role. Required\n  for the licensed parts of the dataset, notably **company data** (which firm\n  built what, in which role) and structure **Timeline data**, and for bulk-scale\n  reading beyond the free quotas.\n\nAn endpoint you may not use answers `401` when you are not signed in and `403`\nwhen you are signed in but your plan or role does not cover it. It never returns\na silent empty result.\n\n**[More details about SKYDB API](/api/)**: plans, quotas, licensing and how to\nrequest a token.\n\n## Base URL and versioning\n\n    https://www.skydb.net/api/v1\n\nThe major version is part of the path. Breaking changes ship as a new major\nversion; additive fields can appear inside `v1` at any time, so clients must\nignore unknown properties rather than fail on them.\n\n## Authentication\n\nMost read endpoints are public. Anything that identifies a person, edits data,\nor pages deep into a list needs an authenticated session.\n\nThere are two ways in. **API tokens** are the one to use for anything\nautomated; the session cookie exists because the website itself signs in that\nway.\n\n### API token (recommended)\n\nA standard RFC 6750 Bearer token. Send it on every request and nothing else is\nneeded. No cookie jar or CSRF token is required, and it works for reads and writes alike.\n\n    curl -H 'Authorization: Bearer <your-token>' \\\n         https://www.skydb.net/api/v1/account/me\n\nCreate and revoke your own under\n[Settings \u2192 API](https://www.skydb.net/settings/api/). The token is shown once,\nat creation: only its hash is stored, so it cannot be recovered later. If you\nlose it, revoke it and create another. Revocation takes effect on the next\nrequest, and a token can be given an expiry date when you create it.\n\nA token carries exactly the permissions of the account it belongs to: it is not\na way around a plan or a role. Issuing tokens requires an **Insights or API\nplan**. See [plans](https://www.skydb.net/business/) or write to\ninfo@skydb.net.\n\n### Session cookie\n\nPost credentials to `POST /api/v1/auth/signin` as `{\"email\":\"\u2026\",\"password\":\"\u2026\"}`\nand send the cookie you receive on subsequent calls. Writes additionally need the\nCSRF token the sign-in response returns (or `GET /api/v1/auth/csrf-token`) in an\n`X-SKYDB-CSRF` header. A cookie travels automatically, so that second factor is\nwhat stops another site from acting as you.\n\nUnauthenticated calls to a gated endpoint return `401` with code\n`auth.signin_required`; a rejected token also answers `401`, whether it is\nunknown, revoked or expired. An authenticated caller lacking the required role or\nservice plan gets `403` (`auth.admin_required` / `auth.service_required`).\n\n## Response envelope\n\nEvery response, success or failure, uses one envelope. The shape is\nasymmetric: the *absence* of `code` / `errors` is the success signal.\n\nSuccess:\n\n    {\n      \"ok\": true,\n      \"data\": { \u2026 },\n      \"meta\": {\n        \"timestamp\": \"2026-08-02T14:31:07Z\",\n        \"request_id\": \"b3f1\u2026\",\n        \"api_version\": \"v1\"\n      }\n    }\n\nError:\n\n    {\n      \"ok\": false,\n      \"code\": \"not_found\",\n      \"message\": \"Structure not found.\",\n      \"meta\": { \u2026 }\n    }\n\nBranch on `code`. It is a stable English identifier. `message` is localized to\nthe request language and is meant for humans, not for control flow. Validation\nfailures add a per-field `errors` array. Always include `meta.request_id` when\nreporting a problem; it identifies the exact request in our logs.\n\n## Dates and times\n\nEvery timestamp in a response is **RFC 3339 UTC, to the second**:\n\n    \"2026-08-03T07:05:24Z\"\n\nAlways UTC, always `Z`, never a local offset and never fractional seconds, so\n`new Date(value)` and every standard date parser accept it as-is, and two\ntimestamps can be compared as plain strings.\n\nNot to be confused with the dataset's own **dates**, which are calendar values,\nnot instants: a building's completion or demolition date is often known only to\nthe year or the month and is returned as a plain `YYYY-MM-DD`, `YYYY-MM` or\n`YYYY`. A partial date means the rest is unknown. It is not zero-filled and\nmust not be read as the first of the month.\n\n## Status codes\n\n| Code | `code` | Meaning |\n|---|---|---|\n| 200 | none | Success. |\n| 400 | `validation.failed`, `validation.invalid` | Malformed or rejected input. |\n| 401 | `auth.signin_required` | No valid session or token. |\n| 403 | `auth.admin_required`, `auth.service_required` | Authenticated but not permitted. |\n| 404 | `not_found` | No such record, or it is not visible to you. |\n| 409 | `conflict` | Conflicting write, e.g. a suspected duplicate structure. |\n| 429 | `rate_limited` | Quota exhausted. |\n| 500 | `internal_error` | Our fault. Retry, then report with the `request_id`. |\n\n## Pagination\n\nList endpoints take `from` (zero-based row offset) and `pagesize` (rows per\npage, default and hard maximum **100**). Page one of a list is public; paging\nbeyond it requires a session. The limit is an anti-scraping measure, not a\npaywall. Walk a result set with `from=0,100,200,\u2026`, not with a larger page.\n\nPaginated responses carry the totals under `meta.pagination`:\n\n    \"pagination\": { \"page\": 1, \"page_size\": 100, \"total_count\": 4312,\n                    \"total_pages\": 44, \"has_more\": true }\n\n## Rate limits\n\nQuotas are per caller and per endpoint class (`read_light` for lookups and list\npages, `read_heavy` for detail fetches and search aggregations, `map` for\nviewport queries, which has its own budget). Anonymous callers get 300\n`read_light` requests per hour; a signed-in account 2 000, rising to 10 000 once\nthe account is established. Contribution endpoints are never gated.\n\n**Important for clients:** an over-quota request is answered with HTTP **200**\nand a stub body, not a `429`. The stub carries `ratelimit_class`, `stage` and\n`utilization_pct` and contains no data. Treat a response whose body holds\n`ratelimit_class` as throttled, back off, and retry later. Checking the status\ncode alone will silently read empty results as real ones.\n\n## Terms\n\nData is licensed, not public domain. Attribution and redistribution terms depend\non your plan. See [skydb.net/business](https://www.skydb.net/business/) or write\nto info@skydb.net. Bulk extraction outside your quota is a terms violation and is\nblocked automatically.\n",
        "termsOfService": "https://www.skydb.net/terms-conditions/",
        "contact": {
            "name": "SKYDB API Support",
            "url": "https://www.skydb.net/contact/",
            "email": "info@skydb.net"
        },
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "https://www.skydb.net",
            "description": "Production"
        }
    ],
    "paths": {
        "/api/v1/auth/join": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Register an account.",
                "description": "Creates a free SKYDB membership and sends a confirmation email. The\naccount exists immediately but stays unconfirmed until the emailed code\nis submitted to `POST /auth/confirm-email`.\n\nProtected by a bot challenge: pass the widget's `turnstile_token`. The\ncheck fails open when no challenge is configured for the environment, so\nlocal and test setups work without it.",
                "operationId": "post_api_auth_join",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email",
                                    "password"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "password": {
                                        "type": "string",
                                        "format": "password"
                                    },
                                    "firstname": {
                                        "type": "string"
                                    },
                                    "lastname": {
                                        "type": "string"
                                    },
                                    "turnstile_token": {
                                        "description": "Bot-challenge token from the sign-up widget.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/auth/logout": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Sign out.",
                "description": "Ends the session and clears the remember-me cookie.",
                "operationId": "post_api_auth_logout",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/auth/impersonate/stop": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Stop impersonating.",
                "description": "Returns the session to the original administrator. Requires only a\nsession, deliberately not admin rights. While impersonating, the\nsession carries the target member's permissions, so an admin gate here\nwould strand the administrator inside the other account.",
                "operationId": "post_api_auth_impersonate_stop",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/auth/confirm-email": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Confirm your email address.",
                "description": "Submits the code from the confirmation email.",
                "operationId": "post_api_auth_confirm_email",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "code"
                                ],
                                "properties": {
                                    "code": {
                                        "description": "Code from the confirmation email.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/auth/confirm-email-resend": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Resend the confirmation email.",
                "description": "Issues a fresh confirmation code for the signed-in member's address.",
                "operationId": "post_api_auth_confirm_email_resend",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/auth/context": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Get the current session context.",
                "description": "Who you are signed in as, and what you are allowed to do, account id,\ndisplay name, roles and service plans. Read this instead of inferring\npermissions client-side; it is the same source the server gates on.",
                "operationId": "get_api_auth_context",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/auth/magic-link-email": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Send a magic sign-in link.",
                "description": "Emails a one-time sign-in link, so a member who has forgotten their\npassword can get in without resetting it. The link also reactivates a\ndormant account, which is the usual route back in for members returning\nfrom the legacy Phorio era.\n\nAlways answers success, whether or not the address is registered. This\nprevents anonymous callers from using it to discover member email\naddresses.",
                "operationId": "post_api_auth_magic_link_email",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "redirect_to": {
                                        "description": "Path to land on after the link is used.",
                                        "type": "string"
                                    },
                                    "turnstile_token": {
                                        "description": "Bot-challenge token.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/auth/signout": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Sign out (legacy path).",
                "description": "Kept for older clients. `POST /auth/logout` is the current endpoint.",
                "operationId": "post_api_auth_signout",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/me": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Get your own account.",
                "description": "The signed-in member's own record, including fields nobody else sees.",
                "operationId": "get_api_account_me",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/accounts/system": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Create an import or automation account.",
                "description": "The account a campaign writes under (one per campaign and criteria\nset, named \"Import ...\" or \"Automation ...\" with the full date). An\nactive account with the same name or email is never duplicated: the\ncall answers `409 account_exists` with the existing id. With\n`issue_token=true` the matching `sdk.import` / `sdk.automation` token\nis issued in the same step and returned once in `data.token`.\nAdministrators, from a signed-in session. The console form is\n`bin/console skydb:system-account:create`.",
                "operationId": "post_api_accounts_system_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name",
                                    "services"
                                ],
                                "properties": {
                                    "name": {
                                        "description": "Starts with \"Import\" or \"Automation\", names the campaign, ends with the date.",
                                        "type": "string",
                                        "maxLength": 120,
                                        "example": "Import UK Local Authorities 2026-09-06"
                                    },
                                    "services": {
                                        "type": "string",
                                        "enum": [
                                            "import",
                                            "automation"
                                        ]
                                    },
                                    "note": {
                                        "description": "Internal description of what the account does (accountaboutmeinternal).",
                                        "type": "string"
                                    },
                                    "email": {
                                        "description": "Login email; derived from the name when omitted.",
                                        "type": "string"
                                    },
                                    "issue_token": {
                                        "description": "Also issue the SDK token.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/validate-password": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Check a password against the policy.",
                "description": "Validates a candidate password and reports what is wrong with it, so a\nsign-up form can tell the user before submitting. Nothing is stored.",
                "operationId": "post_api_account_validate_password",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "password"
                                ],
                                "properties": {
                                    "password": {
                                        "type": "string",
                                        "format": "password"
                                    },
                                    "password_repeat": {
                                        "description": "Checked for equality when supplied.",
                                        "type": "string",
                                        "format": "password"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/{id}/profile": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Get a member's profile.",
                "description": "The public-facing profile of one member: display name, location, avatar\nand contribution summary.",
                "operationId": "get_api_account_profile",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Account id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/account/{id}/stats": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Get a member's contribution statistics.",
                "description": "How much this member has contributed, edits, uploads, structures\ncreated.",
                "operationId": "get_api_account_stats",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Account id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/account/generate-password": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Generate a password suggestion.",
                "description": "Returns a policy-compliant random password for the sign-up form.",
                "operationId": "get_api_account_generate_password",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/account/email-registered": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Check whether an email is registered.",
                "description": "Drives the sign-in form's \"we know you\" branch.\n\nIt reports **active** accounts only. A dormant account (as most legacy\nPhorio members are) answers \"not registered\" here even though\nit exists, so do not treat a negative as proof that the address is free.\nThe way back into a dormant account is the magic link or a password\nreset, both of which reach it and reactivate it.",
                "operationId": "get_api_account_email_registered",
                "parameters": [
                    {
                        "name": "email",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "email"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/account/{id}/picture-url": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Get a member's avatar URL.",
                "description": "Returns the URL of the member's portrait, or the default avatar when\nthey have not uploaded one.",
                "operationId": "get_api_account_picture_url",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Account id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/account/{id}/view-url": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Get a member's profile URL.",
                "description": "The canonical link to the member's profile page, built\nserver-side so clients do not hand-assemble entity URLs.",
                "operationId": "get_api_account_view_url",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Account id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/account/password-reset-email": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Request a password reset email.",
                "description": "Sends a reset link. Like the magic link, it reaches dormant accounts and\nreactivates them, and it always answers success so the endpoint cannot\nbe used to test which addresses are registered.",
                "operationId": "post_api_account_password_reset_email",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "turnstile_token": {
                                        "description": "Bot-challenge token.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/password-reset-email-self": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Send a password-reset email to the signed-in account's own address.",
                "description": "The \"Set New Password\" button on /settings/#signin: same reset email as\n/request-password/, but the session IS the bot gate (no Turnstile) and\nthe address is always the caller's own, nothing user-supplied.",
                "operationId": "post_api_account_password_reset_email_self",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/password-reset": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Set a new password.",
                "description": "Consumes the token from the reset email and stores the new password. The\ntoken is single-use.",
                "operationId": "post_api_account_password_reset",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "token",
                                    "password"
                                ],
                                "properties": {
                                    "token": {
                                        "description": "Token from the reset email. Single-use.",
                                        "type": "string"
                                    },
                                    "password": {
                                        "type": "string",
                                        "format": "password"
                                    },
                                    "password_repeat": {
                                        "type": "string",
                                        "format": "password"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/accounts/editors": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "List editors.",
                "description": "The members who maintain the database. This is the directory behind the\npublic members page.",
                "operationId": "get_api_accounts_editors",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/accounts/search": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Search members (typeahead).",
                "description": "Name lookup over members, for pickers such as the mention autocomplete.",
                "operationId": "get_api_accounts_search",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Search text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/account/{id}": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Get a member.",
                "description": "One member's record. Answers `404` for an account that is inactive or\ndeleted, so a hidden member is indistinguishable from one that never\nexisted.",
                "operationId": "get_api_account_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Account id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "account"
                ],
                "summary": "Update a member.",
                "description": "Members can edit their own account; administrators can edit any.\nSend only the fields you are changing.\n\n**The email address is never written directly.** Supplying\n`accountemail` starts a confirmation flow instead: a verification link\ngoes to the new address and the change only lands once\n`POST /account/email-change/confirm` consumes the token. The response\nreports the change as pending, not applied. An address already used by\nanother account is rejected.\n\n`accountservices`, `accounttype` and\n`deleted` are administrator-only and are **silently ignored** for\nanyone else. A non-admin sending them gets a success response in which\nthose fields simply did not change. Check the returned `updated` list to\nsee what was actually written.",
                "operationId": "put_api_account_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Account id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "accountname": {
                                        "description": "Display name.",
                                        "type": "string"
                                    },
                                    "accountfirstname": {
                                        "type": "string"
                                    },
                                    "accountlastname": {
                                        "type": "string"
                                    },
                                    "accountemail": {
                                        "description": "Starts the email-change confirmation flow; never written directly.",
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "accountaboutmeinternal": {
                                        "type": "string"
                                    },
                                    "accountbirthdate": {
                                        "type": "string"
                                    },
                                    "accountcompany": {
                                        "type": "string"
                                    },
                                    "accountaddressline1": {
                                        "description": "Billing address.",
                                        "type": "string"
                                    },
                                    "accountaddressline2": {
                                        "description": "Billing address.",
                                        "type": "string"
                                    },
                                    "accountpostcode": {
                                        "description": "Billing address.",
                                        "type": "string"
                                    },
                                    "accountcity": {
                                        "type": "string"
                                    },
                                    "accountstate": {
                                        "description": "Billing address state/province (plain name, currently used for US addresses).",
                                        "type": "string"
                                    },
                                    "accountcountry": {
                                        "type": "string"
                                    },
                                    "accountvat": {
                                        "description": "VAT identification number, printed on invoices.",
                                        "type": "string"
                                    },
                                    "accountphone": {
                                        "type": "string"
                                    },
                                    "accounttelegram": {
                                        "description": "Telegram handle, stored internally only. Accepts \"@name\", \"name\" or a t.me link; stored as the bare handle without the leading @.",
                                        "type": "string"
                                    },
                                    "accountwebsite": {
                                        "type": "string"
                                    },
                                    "accounttwitter": {
                                        "type": "string"
                                    },
                                    "accountfileownername": {
                                        "description": "Name credited on your uploaded photos.",
                                        "type": "string"
                                    },
                                    "accountlanguage": {
                                        "description": "Interface language, ISO 639-1.",
                                        "type": "string"
                                    },
                                    "accountmetric": {
                                        "description": "1 = metric, 2 = imperial. Anything else falls back to metric.",
                                        "type": "integer",
                                        "enum": [
                                            1,
                                            2
                                        ]
                                    },
                                    "accountpanoramas": {
                                        "description": "Show the city header photo above the location bar.",
                                        "type": "boolean"
                                    },
                                    "accountdarkmode": {
                                        "description": "Use the SKYDB dark color mode.",
                                        "type": "boolean"
                                    },
                                    "accountinteractiveresultrows": {
                                        "description": "Enable click and double-click actions on result rows.",
                                        "type": "boolean"
                                    },
                                    "accountfilesarewatermarked": {
                                        "description": "Default watermark setting for own photo uploads.",
                                        "type": "boolean"
                                    },
                                    "accountfilesalloworiginaldownload": {
                                        "description": "Allow public downloads of raster originals when the per-file setting is automatic.",
                                        "type": "boolean"
                                    },
                                    "accounttimezone": {
                                        "description": "Display time zone as an IANA tz identifier. Empty string resets to automatic detection. This is not a UTC offset because an offset cannot express daylight saving.",
                                        "type": "string",
                                        "example": "Europe/Berlin"
                                    },
                                    "accountcurrency": {
                                        "description": "Display currency, ISO 4217 alpha-3. Empty string resets to \"derive from country\". Presentment only: prices exist per currency and are never converted.",
                                        "type": "string",
                                        "example": "EUR"
                                    },
                                    "accountregionalformat": {
                                        "description": "BCP 47 regional-format locale. Empty string resets to browser detection.",
                                        "type": "string",
                                        "example": "de-DE"
                                    },
                                    "accountdateformat": {
                                        "description": "Date presentation format. Empty string uses the regional format.",
                                        "type": "string",
                                        "enum": [
                                            "",
                                            "dmy_slash",
                                            "dmy_dot",
                                            "dmy_dash",
                                            "mdy_slash",
                                            "mdy_dash",
                                            "ymd_dash",
                                            "ymd_slash",
                                            "ymd_dot",
                                            "dmy_text",
                                            "mdy_text",
                                            "ymd_text"
                                        ]
                                    },
                                    "accounttimeformat": {
                                        "description": "Clock presentation format. Empty string uses the regional format.",
                                        "type": "string",
                                        "enum": [
                                            "",
                                            "12h",
                                            "24h"
                                        ]
                                    },
                                    "accounthomecityobjectid": {
                                        "description": "Public Home City ObjectID. Must identify an active City Region (regiongroupid 6). Zero or empty clears it.",
                                        "type": "integer",
                                        "format": "int64",
                                        "nullable": true
                                    },
                                    "accountcity_keepprivate": {
                                        "type": "boolean"
                                    },
                                    "accountcountry_keepprivate": {
                                        "type": "boolean"
                                    },
                                    "accountphone_keepprivate": {
                                        "type": "boolean"
                                    },
                                    "accounttwitter_keepprivate": {
                                        "type": "boolean"
                                    },
                                    "accounthidefromsearch": {
                                        "type": "boolean"
                                    },
                                    "accounthidecontributions": {
                                        "description": "Hide the contribution-count tiles on the public profile.",
                                        "type": "boolean"
                                    },
                                    "accountservices": {
                                        "description": "Administrators only. Role and plan flags.",
                                        "type": "string"
                                    },
                                    "accounttype": {
                                        "description": "Administrators only.",
                                        "type": "string"
                                    },
                                    "deleted": {
                                        "description": "Administrators only.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/close": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Close your own account.",
                "description": "Retires the account, revokes its API tokens, ends the session and\nsends a confirmation mail. The contributions stay attributed. Accounts\nwith a password confirm it in `password`; accounts that only ever\nsigned in through a provider have none and close without it.\n`reason` is an optional free text kept with the closing. Administrators\ncannot close their own account here.",
                "operationId": "post_api_account_close",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "password": {
                                        "description": "Required when the account has a password.",
                                        "type": "string",
                                        "format": "password"
                                    },
                                    "reason": {
                                        "description": "Optional: why the account is closed.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/email-change/confirm": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Confirm an email change.",
                "description": "Consumes the token sent to the **new** address and completes the change.\nRequesting the change stores it as pending; the address only moves once\nthis call proves the new mailbox is reachable.",
                "operationId": "post_api_account_email_change_confirm",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "token"
                                ],
                                "properties": {
                                    "token": {
                                        "description": "Token from the verification email. Single-use.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/tokens": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "List your API tokens.",
                "description": "Metadata only, name, prefix, creation, expiry, last use, revocation\ndate and whether the token still works. The token itself is not stored\nand cannot be shown again.",
                "operationId": "get_api_account_tokens_list",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Create an API token.",
                "description": "The response carries the token in `data.token`, **the only time it is\never available**. Store it before closing the page; if it is lost,\nrevoke it and create another.",
                "operationId": "post_api_account_tokens_create",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "description": "What the token is for, e.g. \"Import server\".",
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "expires_in_days": {
                                        "description": "Optional lifetime. Omit for a token that does not expire.",
                                        "type": "integer"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/tokens/{id}": {
            "delete": {
                "tags": [
                    "account"
                ],
                "summary": "Revoke an API token.",
                "description": "Takes effect on the next request. Revoking is permanent; the row stays\nso a compromised token remains visible in the account's history.",
                "operationId": "delete_api_account_tokens_revoke",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Token id from the list.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/account/usage": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Your API usage.",
                "description": "Totals for the window plus two breakdowns: per token and per endpoint.\n`available: false` means the request log could not be read, which is\nnot the same as \"you made no calls\", and the page says so rather than\nshowing a confident zero.",
                "operationId": "get_api_account_usage",
                "parameters": [
                    {
                        "name": "days",
                        "in": "query",
                        "description": "Window in days: 7, 30, 90 or 365. Defaults to 30.",
                        "schema": {
                            "type": "integer",
                            "default": 30
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/auth/signin": {
            "post": {
                "tags": [
                    "account"
                ],
                "summary": "Sign in.",
                "description": "Authenticates with email and password and establishes the session\ncookie. This is the endpoint behind the `sessionCookie` security scheme;\neverything gated by \"Member\" or \"Paid plan\" needs a session from here.\n\nThe response also returns a **fresh CSRF token**. Signing in migrates\nthe session as protection against fixation, which invalidates the token\na page picked up while anonymous, a client that keeps the old one gets\n`csrf_invalid` on its next write. Adopt the returned token.\n\nA dormant account is reactivated automatically on a correct password.",
                "operationId": "post_api_auth_signin",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email",
                                    "password"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "password": {
                                        "type": "string",
                                        "format": "password"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Signed in. Carries the account id, name, service flags, post-sign-in redirect and a fresh CSRF token."
                    },
                    "401": {
                        "description": "Email or password is incorrect (`auth.signin_failed`)."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/auth/csrf-token": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Get a CSRF token.",
                "description": "Session-based writes need a CSRF token. Fetch one here if you do not\nalready hold a valid one, after signing in, prefer the token that call\nreturned. Bearer-token clients do not need this: they only make safe\nrequests.",
                "operationId": "get_api_auth_csrf_token",
                "responses": {
                    "200": {
                        "description": "The token to send on subsequent non-GET requests."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/collections/migrate": {
            "get": {
                "tags": [
                    "internal"
                ],
                "summary": "Preview the next legacy Collection or CollectionItem batch.",
                "operationId": "get_api_collection_migrate_preview",
                "parameters": [
                    {
                        "name": "phase",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "collections",
                                "items"
                            ]
                        }
                    },
                    {
                        "name": "after_id",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 0
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "maximum": 250,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "internal"
                ],
                "summary": "Migrate the next bounded Collection or CollectionItem batch.",
                "operationId": "post_api_collection_migrate_apply",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "phase"
                                ],
                                "properties": {
                                    "phase": {
                                        "type": "string",
                                        "enum": [
                                            "collections",
                                            "items"
                                        ]
                                    },
                                    "after_id": {
                                        "type": "integer",
                                        "minimum": 0
                                    },
                                    "limit": {
                                        "type": "integer",
                                        "maximum": 250,
                                        "minimum": 1
                                    },
                                    "defer_projection": {
                                        "description": "Defer entity and Object index writes until a managed rebuild.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/credits": {
            "get": {
                "tags": [
                    "commerce"
                ],
                "summary": "What this account may still spend, per usage product.",
                "description": "The dialog and the credits page both state the balance before anything\nis bought, so the number comes from one place rather than each surface\ncounting grants for itself. A signed-out caller gets zeros rather than a\nrefusal: the \"How it works\" step is readable without an account, and a\nbalance of nothing is the true answer for nobody in particular.",
                "operationId": "get_api_credits_balance",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/credits/grant": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "summary": "Grant credits to the signed-in account.",
                "description": "The admin counterpart to buying: support settles a complaint, an\noperator compensates a failed export, a plan is honoured by hand. It\nwrites the same grant a purchase writes, so the balance, the expiry and\nthe spending order stay one mechanism.\n\nThe reason is required and lands in the grant row: a credit that appears\nwithout one cannot be answered for later.",
                "operationId": "post_api_credits_grant",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "quantity": {
                                        "description": "Credits to add. At least 1.",
                                        "type": "integer"
                                    },
                                    "reason": {
                                        "description": "Why they were granted. Recorded on the grant.",
                                        "type": "string"
                                    },
                                    "kind": {
                                        "description": "Usage kind. Defaults to export_row.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/credits/remove": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "summary": "Take credits off the signed-in account.",
                "description": "The counterpart to granting, for a grant made in error or a compensation\nwithdrawn. It runs through the same spend path an export uses, so the\ncredits come off oldest expiry first and the movement lands in the same\nledger. All or nothing: a balance too small is refused rather than\npartly taken, which would leave the account in a state nobody chose.",
                "operationId": "post_api_credits_remove",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "quantity": {
                                        "description": "Credits to remove. At least 1.",
                                        "type": "integer"
                                    },
                                    "reason": {
                                        "description": "Why they were removed. Recorded on the ledger.",
                                        "type": "string"
                                    },
                                    "kind": {
                                        "description": "Usage kind. Defaults to export_row.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/credits/history": {
            "get": {
                "tags": [
                    "commerce"
                ],
                "summary": "The credit movements of the signed-in account, newest first.",
                "description": "Every grant and every spend writes one ledger row, so this is the answer\nto \"where did this balance come from\": a granted credit and an exported\nrow are the same kind of event, told apart by the sign.",
                "operationId": "get_api_credits_history",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/checkout/session": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "summary": "Start checkout.",
                "description": "Creates a Stripe Checkout Session and returns its hosted URL; send the\nbuyer there. Three ways to say what is being bought, in this order of\nprecedence: `share` checks out an entire shopping cart, `sku` buys one\nnamed product, and `file_id` is the older photo-purchase shorthand.\n\nAmounts are always resolved server-side from the catalog. The client\nnever supplies a price.",
                "operationId": "post_api_checkout_session",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "share": {
                                        "description": "Shopping cart token. Checks out every item in that cart.",
                                        "type": "string"
                                    },
                                    "sku": {
                                        "description": "Single product identifier.",
                                        "type": "string"
                                    },
                                    "file_id": {
                                        "description": "Photo to buy. Legacy shorthand for the default photo product.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "product_ref": {
                                        "description": "What the product refers to.",
                                        "type": "string"
                                    },
                                    "email": {
                                        "description": "Pre-fills the buyer email on the Stripe page.",
                                        "type": "string",
                                        "format": "email"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/checkout/usage": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "summary": "Quote and buy a counted quantity: pay-as-you-go export rows.",
                "description": "\u26a0\ufe0f The request says WHICH rows, never how many and never what they cost.\nThe quantity is counted here, from the collection the caller named, and\nthe amount comes from the graduated bands. Accepting a client-supplied\ncount would hand the customer the pricing lever.\n\n`quote_only` returns the price without starting a checkout, which is what\nthe page shows before the customer commits.",
                "operationId": "post_api_checkout_usage",
                "responses": {
                    "200": {
                        "description": "The price for the counted rows, and a checkout URL unless quote_only."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/subscription/portal": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "summary": "Open the billing portal.",
                "description": "Returns a one-time Stripe Customer Portal URL where the signed-in member\nmanages their subscription, payment method, invoices, cancellation.\nSend them to `data.url`.",
                "operationId": "post_api_subscription_portal",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "502": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/stripe/webhook": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "summary": "Stripe webhook receiver.",
                "description": "**For Stripe, not for you.** Payment confirmations, subscription\nlifecycle events and failed invoices arrive here.\n\nThe signature *is* the authentication: the `Stripe-Signature` header is\nHMAC-verified against the raw request body and the endpoint secret, so\nthe body must be forwarded byte-for-byte, any middleware that re-encodes\nJSON breaks verification. Handling is idempotent on the Stripe event id,\nA verified and successfully handled event answers `200`. Processing\nfailures answer `500` so Stripe retries instead of silently losing the\npayment/subscription update.",
                "operationId": "post_api_stripe_webhook",
                "requestBody": {
                    "description": "Raw Stripe event payload.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Event accepted (or already processed)."
                    },
                    "400": {
                        "description": "Signature verification failed."
                    },
                    "500": {
                        "description": "Processing failed; Stripe should retry the event."
                    }
                },
                "security": [
                    {
                        "stripeSignature": []
                    }
                ]
            }
        },
        "/api/v1/application/draft": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "Get your editor application draft.",
                "description": "Editor status is applied for and peer-reviewed. This returns the\nsigned-in member's own draft. The row is pinned to the session, so\nthere is no way to read someone else's.",
                "operationId": "get_api_application_draft_get",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Save your editor application draft.",
                "description": "Stores work in progress without submitting it. Pinned to your own\nsession like the read.",
                "operationId": "post_api_application_draft_save",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "description": "Application form fields.",
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/application/submit": {
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Submit your editor application.",
                "description": "Hands the draft to peer review. Applications are assessed by existing\neditors, not granted automatically.",
                "operationId": "post_api_application_submit",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/application/{id}/vote": {
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Vote on a pending editor application.",
                "description": "Editor applications are decided by the people who already hold the\nrole: editors, senior editors and administrators vote approve or\nreject, and the majority closes the application once five votes are in.\nAn applicant cannot vote on their own application, and a second vote\nfrom the same reviewer replaces their first rather than counting twice.",
                "operationId": "post_api_application_vote",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Application id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "properties": {
                                    "vote": {
                                        "type": "string",
                                        "enum": [
                                            "approve",
                                            "reject"
                                        ]
                                    },
                                    "note": {
                                        "description": "Optional reason, shown to the applicant.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/application/{id}/unvote": {
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Take back your own vote on a pending application.",
                "description": "Withdrawing is the voter's own business, so it needs the same reviewer\nright the vote needed and touches nobody else's row. The vote is deleted\nrather than flagged: a withdrawn vote must not count, and the reviewer is\noffered the application again as if they had never voted.",
                "operationId": "post_api_application_unvote",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Application id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/application/{id}/decide": {
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Decide an application without waiting for the peer vote (administrators).",
                "operationId": "post_api_application_decide",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/application/{id}": {
            "delete": {
                "tags": [
                    "community"
                ],
                "summary": "Take an application out of the review queue (administrators).",
                "operationId": "delete_api_application_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/application/{id}/answers": {
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Correct the answers of a pending application (administrators).",
                "operationId": "post_api_application_answers",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/definition/{id}": {
            "get": {
                "tags": [
                    "definition"
                ],
                "summary": "Get a data definition.",
                "description": "Definitions are SKYDB's published measurement standards, what exactly\n\"height\", \"floor\" or \"high-rise\" mean here, and how each is measured.\nThey are the reason two SKYDB records are comparable, and the authority\nfor any threshold: read the definition rather than assuming a number.\nCategory keys and related Definition lists require a signed-in member.",
                "operationId": "get_api_definition_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Definition ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            },
            "put": {
                "tags": [
                    "definition"
                ],
                "summary": "Create or update a data definition.",
                "description": "Post to `id=0` to create. Administrators and senior editors only;\nchanging a definition changes the meaning of every record measured\nagainst it.",
                "operationId": "put_api_definition_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Definition ObjectID, or `0` to create.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "title": {
                                        "description": "The term being defined.",
                                        "type": "string"
                                    },
                                    "type": {
                                        "description": "Strict standard, flexible standard, or reaction mask.",
                                        "type": "string",
                                        "enum": [
                                            "standard",
                                            "compound",
                                            "mask"
                                        ]
                                    },
                                    "altnames": {
                                        "description": "Synonyms this term is also known by.",
                                        "type": "string"
                                    },
                                    "memo": {
                                        "description": "The definition text.",
                                        "type": "string"
                                    },
                                    "hiddentext": {
                                        "description": "Internal notes, not published.",
                                        "type": "string"
                                    },
                                    "keywords": {
                                        "description": "Comma-separated search phrases, published as links on the definition page.",
                                        "type": "string"
                                    },
                                    "featured": {
                                        "description": "Show this term in the Featured definitions strip.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "definition"
                ],
                "summary": "Delete a data definition.",
                "description": "Soft delete. Administrators only (operator 2026-08-19; senior editors\nwrite the texts and move terms in the tree, but do not remove them).\nA definition that is still used by the tree, schema, taxonomy, examples,\nTimeline/recognition configuration, or comments is refused with 409.",
                "operationId": "delete_api_definition_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Definition ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "description": "The definition is still referenced by another active record."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/definition/{id}/delete-check": {
            "get": {
                "tags": [
                    "definition"
                ],
                "summary": "Check whether a definition can be deleted without changing it.",
                "description": "The editor calls this before it offers the destructive confirmation.\nThe DELETE action repeats the same authoritative PostgreSQL guard, so a\nconnection added between the check and the final click still blocks.",
                "operationId": "get_api_definition_delete_check",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Definition ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/definition/{id}/example/{kind}/{refid}": {
            "post": {
                "tags": [
                    "definition"
                ],
                "summary": "Link an example to a data definition.",
                "description": "A definition can point at the objects that show what it means\n(`kind=object` - a building, region, company or street; `structure`\nis accepted as the older spelling of the same thing) and at the\nphotos that illustrate it (`kind=file`). Administrators and senior\neditors only, same gate as the text.",
                "operationId": "post_api_definition_example_add",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Definition ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "kind",
                        "in": "path",
                        "description": "What is being linked.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "object|structure|file",
                            "enum": [
                                "object",
                                "structure",
                                "file"
                            ]
                        }
                    },
                    {
                        "name": "refid",
                        "in": "path",
                        "description": "Object id or file id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "definition"
                ],
                "summary": "Unlink an example from a data definition.",
                "description": "Soft delete of the link only - neither the building nor the photo is\ntouched. Administrators and senior editors only.",
                "operationId": "delete_api_definition_example_remove",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Definition ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "kind",
                        "in": "path",
                        "description": "What is being unlinked.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "object|structure|file",
                            "enum": [
                                "object",
                                "structure",
                                "file"
                            ]
                        }
                    },
                    {
                        "name": "refid",
                        "in": "path",
                        "description": "Object id or file id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/definition/{id}/parent/{parentid}": {
            "post": {
                "tags": [
                    "definition"
                ],
                "summary": "Move a definition in the tree.",
                "description": "The parent ObjectID is the definition tree: breadcrumb,\nsub-definitions and related terms all read it. A value of 0 detaches the definition\ninto a root. Refused when the target is the definition itself or one\nof its own descendants. Administrators and senior editors only.",
                "operationId": "post_api_definition_parent_set",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Definition ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "parentid",
                        "in": "path",
                        "description": "New parent Definition ObjectID, or 0 for no parent.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/definitions": {
            "get": {
                "tags": [
                    "definition"
                ],
                "summary": "List data definitions.",
                "description": "The published measurement standards, browsable and searchable. Use\n`letter` for the A to Z index the standards page is built on.",
                "operationId": "get_api_definitions_list",
                "parameters": [
                    {
                        "name": "type",
                        "in": "query",
                        "description": "Restrict to one definition type.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "parent_id",
                        "in": "query",
                        "description": "Only definitions nested under this one. Signed-in members only.",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "keyword",
                        "in": "query",
                        "description": "Full-text filter over term and text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "letter",
                        "in": "query",
                        "description": "First letter, for the A to Z index.",
                        "schema": {
                            "type": "string",
                            "maxLength": 1
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offset",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/faqtypes": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "List all active FAQ topics.",
                "operationId": "get_api_faqtypes_list",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/faqtypes/{id}": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "Get one active FAQ topic.",
                "operationId": "get_api_faqtype_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "FAQ topic id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "community"
                ],
                "summary": "Create or update an FAQ topic.",
                "description": "Topics group FAQ entries. Post to `id=0` to create. Editors and above.",
                "operationId": "put_api_faqtype_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "FAQ topic id, or `0` to create.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "title": {
                                        "type": "string"
                                    },
                                    "key": {
                                        "description": "Stable slug used in URLs.",
                                        "type": "string"
                                    },
                                    "fileid": {
                                        "description": "Key image: the id of a public SKYDB photo, 0 to clear it.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "description": {
                                        "description": "Rich text shown on the topic page.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "community"
                ],
                "summary": "Delete an FAQ topic.",
                "description": "Soft delete. Administrators only, and only while the group contains no\nlive documents.",
                "operationId": "delete_api_faqtype_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "FAQ topic id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "description": "The group still contains live documents."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/faq/{id}": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "Get an FAQ entry.",
                "description": "One question with its short and full answer.",
                "operationId": "get_api_faq_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "FAQ id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "community"
                ],
                "summary": "Create or update an FAQ entry.",
                "description": "Post to `id=0` to create. Editors and above.",
                "operationId": "put_api_faq_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "FAQ id, or `0` to create.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "title": {
                                        "description": "The question.",
                                        "type": "string"
                                    },
                                    "key": {
                                        "description": "Stable slug used in URLs.",
                                        "type": "string"
                                    },
                                    "faqtype": {
                                        "description": "Topic this entry belongs to.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "abstract": {
                                        "description": "Short answer shown in listings.",
                                        "type": "string"
                                    },
                                    "memo": {
                                        "description": "Full answer.",
                                        "type": "string"
                                    },
                                    "featured": {
                                        "description": "Show the document as a tile in its topic page's \"Featured documents\" strip.",
                                        "type": "boolean"
                                    },
                                    "fileid": {
                                        "description": "Key image for that tile: the id of a public SKYDB photo, 0 to clear it.",
                                        "type": "integer",
                                        "format": "int64"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "community"
                ],
                "summary": "Delete an FAQ entry.",
                "description": "Soft delete. Editors and above.",
                "operationId": "delete_api_faq_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "FAQ id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/faqs": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "List FAQ entries.",
                "description": "Page one is public; paging deeper requires a session, like every other\nlist. Default page size is 50.",
                "operationId": "get_api_faqs_list",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/From"
                    },
                    {
                        "name": "pagesize",
                        "in": "query",
                        "description": "Rows per page.",
                        "schema": {
                            "type": "integer",
                            "default": 50
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "keyword",
                        "in": "query",
                        "description": "Full-text filter.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "key",
                        "in": "query",
                        "description": "Fetch by slug.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "faqtype",
                        "in": "query",
                        "description": "Restrict to one topic.",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "faqform",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "featured",
                        "in": "query",
                        "description": "Only documents marked as featured.",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/forum/categories": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "List forum categories.",
                "description": "The editor forum's top-level boards.",
                "operationId": "get_api_forum_categories",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/forum/threads": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "List forum threads.",
                "description": "Threads in one board, or across all boards when no category is given.",
                "operationId": "get_api_forum_threads",
                "parameters": [
                    {
                        "name": "category",
                        "in": "query",
                        "description": "Category slug to list.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Search text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offset",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Start a forum thread.",
                "description": "`memo` is rich text from the shared editor and may contain account\nmentions.",
                "operationId": "post_api_forum_thread_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "category_id",
                                    "subject",
                                    "memo"
                                ],
                                "properties": {
                                    "category_id": {
                                        "description": "Board to post in.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "subject": {
                                        "type": "string"
                                    },
                                    "memo": {
                                        "description": "Opening post, rich text.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/forum/thread/{id}": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "Get a forum thread.",
                "description": "The thread with its messages in order.",
                "operationId": "get_api_forum_thread_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Thread id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/forum/thread/{id}/reply": {
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Reply to a forum thread.",
                "description": "Appends a message to an existing thread.",
                "operationId": "post_api_forum_thread_reply",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Thread id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "memo"
                                ],
                                "properties": {
                                    "memo": {
                                        "description": "Reply text, rich text.",
                                        "type": "string"
                                    },
                                    "subject": {
                                        "description": "Optional; defaults to the thread subject.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/forum/message/{id}": {
            "delete": {
                "tags": [
                    "community"
                ],
                "summary": "Delete a forum message.",
                "description": "Soft delete. Authors delete their own posts; moderators can delete any.",
                "operationId": "delete_api_forum_message_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Message id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "community"
                ],
                "summary": "Edit a forum message.",
                "description": "Authors edit their own posts; moderators can edit any.",
                "operationId": "patch_api_forum_message_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Message id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "memo": {
                                        "description": "Replacement text.",
                                        "type": "string"
                                    },
                                    "subject": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/forum/category/{id}": {
            "put": {
                "tags": [
                    "community"
                ],
                "summary": "Create or update a forum category.",
                "description": "Post to `id=0` to create. Moderators and above.",
                "operationId": "put_api_forum_category_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Category id, or `0` to create.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "key": {
                                        "description": "Stable slug used in URLs.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "community"
                ],
                "summary": "Delete a forum category.",
                "description": "Soft delete. Only the board's creator or an administrator can remove it.",
                "operationId": "delete_api_forum_category_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Category id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/contact/submit": {
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Submit the contact form.",
                "description": "Routes a message to the right department. Carries spam defences: a\nhidden honeypot field (`_hp`) that must stay empty and a form timestamp\n(`_ts`) that rejects submissions faster than a human could type.",
                "operationId": "post_api_contact_submit",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email",
                                    "message"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "company": {
                                        "type": "string"
                                    },
                                    "phone": {
                                        "description": "Callback phone number.",
                                        "type": "string"
                                    },
                                    "department": {
                                        "description": "Who should receive it.",
                                        "type": "string"
                                    },
                                    "reason": {
                                        "description": "Subject category.",
                                        "type": "string"
                                    },
                                    "desired_date": {
                                        "description": "Requested weekday after the current day in the selected time zone.",
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "desired_time": {
                                        "description": "Requested video-call time in a 30-minute slot from 07:00 to 21:00.",
                                        "type": "string",
                                        "pattern": "^(?:(?:0[7-9]|1[0-9]|20):(?:00|30)|21:00)$"
                                    },
                                    "desired_timezone": {
                                        "description": "IANA time zone for the requested date and time.",
                                        "type": "string",
                                        "example": "Europe/Berlin"
                                    },
                                    "entity": {
                                        "description": "Reported entity type.",
                                        "type": "string"
                                    },
                                    "entity_id": {
                                        "description": "Reported entity ID.",
                                        "type": "integer"
                                    },
                                    "message": {
                                        "type": "string"
                                    },
                                    "_hp": {
                                        "description": "Honeypot. Must be empty, bots that fill it are rejected.",
                                        "type": "string"
                                    },
                                    "_ts": {
                                        "description": "Form render timestamp, used to reject impossibly fast submissions.",
                                        "type": "integer"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/newsletter/subscribe": {
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Subscribe to the newsletter.",
                "description": "First half of a double opt-in: records the address and sends a\nconfirmation email. Nothing is delivered until\n`POST /newsletter/confirm` completes the second half.\n\nDeliberately no bot challenge here. The gate sits on the confirm step,\nwhere it protects the part that actually creates a subscription.",
                "operationId": "post_api_newsletter_subscribe",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "cid": {
                                        "description": "Client identifier for attribution.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/newsletter/confirm": {
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Confirm a newsletter subscription.",
                "description": "Second half of the double opt-in. **Opening the emailed link is not\nenough**. The confirmation page must post the token together with a\npassed bot challenge, so a mail scanner that pre-fetches links cannot\nsubscribe somebody by accident.",
                "operationId": "post_api_newsletter_confirm",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "token"
                                ],
                                "properties": {
                                    "token": {
                                        "description": "Token from the confirmation email.",
                                        "type": "string"
                                    },
                                    "turnstile_token": {
                                        "description": "Bot-challenge token. Required here, unlike the subscribe step.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/datacategory/{id}": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "Get a data category.",
                "description": "Data categories are the controlled vocabularies behind the coded fields:\nevery lifecycle status, structural form, usage, style and material a\nstructure can carry. The id is the dotted code itself\n(`status.4.1`, `02.1.2`), and codes are hierarchical, `status.4`\ncovers everything under it.\n\nResolve codes through this endpoint rather than hardcoding them; the\nvocabulary is extended over time.",
                "operationId": "get_api_datacategory_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Dotted category code.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[A-Za-z0-9_.]+",
                            "example": "status.4.1"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "community"
                ],
                "summary": "Update a category value.",
                "description": "Changes names, flags, sort, definition or field of one value.\nAdministrators.",
                "operationId": "put_api_datacategory_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[a-z][a-z0-9_.]+",
                            "example": "status.4.1"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "description": "Any column of `POST /datacategories`.",
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/datacategories": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "List data categories.",
                "description": "The full coded vocabulary, with labels in every stored language.",
                "operationId": "get_api_datacategories_list",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Create a category value.",
                "description": "Adds a value to the coded vocabulary a category field is validated\nagainst, for example a new usage or status. `model` names a sibling\nvalue whose flags, definition and field the new one inherits; without\nit the parent path (`status.4` for `status.4.2`) supplies field and\ndefinition. The datacategory index follows, so the central validation\naccepts the value at once. Administrators.",
                "operationId": "post_api_datacategories_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "description": "Names in other languages as `name_<iso>`.",
                                "required": [
                                    "categoryid",
                                    "name_en"
                                ],
                                "properties": {
                                    "categoryid": {
                                        "description": "Dotted path; the parent is the path without the last segment.",
                                        "type": "string",
                                        "example": "usage.3.7"
                                    },
                                    "name_en": {
                                        "type": "string"
                                    },
                                    "model": {
                                        "description": "Sibling value to copy flags, definition and field from.",
                                        "type": "string"
                                    },
                                    "datatypeid": {
                                        "type": "string"
                                    },
                                    "parent_id": {
                                        "type": "integer"
                                    },
                                    "objectdefinitionid": {
                                        "description": "Canonical Definition ObjectID.",
                                        "type": "integer"
                                    },
                                    "final": {
                                        "type": "boolean"
                                    },
                                    "selectable": {
                                        "type": "boolean"
                                    },
                                    "sort": {
                                        "type": "integer"
                                    },
                                    "importance": {
                                        "type": "integer"
                                    },
                                    "categoryint": {
                                        "type": "integer"
                                    }
                                },
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/datatypes/search": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "Search data fields (typeahead).",
                "description": "Finds a data field by name across every language, tolerant of accents\nand typos: `wohn` reaches \"residential\", `hauptnutzung` reaches \"primary\nuse\", and a misspelt `residental` still matches.",
                "operationId": "get_api_datatypes_search",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Search text, in any supported language.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "keys",
                        "in": "query",
                        "description": "Restrict to specific field keys.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "objecttypeid",
                        "in": "query",
                        "description": "Restrict to fields valid for one entity type.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/datatypes": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "List data fields.",
                "description": "Every field a record can carry. This is the field catalog behind\n`POST /structure/{id}/data`. Each entry states its value type, unit and\nwhether it is language-dependent or accepts multiple values.",
                "operationId": "get_api_datatypes_list",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "community"
                ],
                "summary": "Create a data field.",
                "description": "Adds a field to the catalog, for example an identifier field a new\nregister import needs. `model` names an existing field whose value\ntype, class, format, importance, tool, visibility and object types the\nnew one inherits; every column may also be given explicitly. The\ndatatype index follows. Administrators, from a signed-in session.",
                "operationId": "post_api_datatypes_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "description": "Names in other languages as `name_<iso>`.",
                                "required": [
                                    "datatypeid",
                                    "name_en"
                                ],
                                "properties": {
                                    "datatypeid": {
                                        "description": "Lowercase letters, digits, underscores.",
                                        "type": "string",
                                        "example": "identifier_inegi_localidad"
                                    },
                                    "name_en": {
                                        "type": "string"
                                    },
                                    "model": {
                                        "description": "Existing field to copy the classification from.",
                                        "type": "string",
                                        "example": "identifier_wikidata"
                                    },
                                    "objecttypeid": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "example": [
                                            "region"
                                        ]
                                    },
                                    "object_reference_types": {
                                        "description": "Concrete Object types accepted as values when valuetypeid is 9.",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "example": [
                                            "street"
                                        ]
                                    },
                                    "valuetypeid": {
                                        "type": "integer"
                                    },
                                    "dataclassid": {
                                        "type": "integer"
                                    },
                                    "dataformatid": {
                                        "type": "integer"
                                    },
                                    "dataimportanceid": {
                                        "type": "integer"
                                    },
                                    "datatoolid": {
                                        "type": "string"
                                    },
                                    "datavisibilityid": {
                                        "type": "integer"
                                    },
                                    "multivalue": {
                                        "type": "boolean"
                                    },
                                    "language_dependent": {
                                        "type": "integer"
                                    },
                                    "datacopy": {
                                        "type": "boolean"
                                    },
                                    "importance": {
                                        "type": "integer"
                                    },
                                    "objectdefinitionid": {
                                        "description": "Canonical Definition ObjectID.",
                                        "type": "integer"
                                    },
                                    "value_min": {
                                        "type": "number"
                                    },
                                    "value_max": {
                                        "type": "number"
                                    }
                                },
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/datatype/{id}": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "Get a data field.",
                "description": "One field's definition: its value type, unit, and the rules that govern\nit. Two matter when writing: a **language-dependent** field stores one\nvalue per language, and a **single-value** field replaces rather than\nappends. Getting either wrong makes earlier values disappear from view.",
                "operationId": "get_api_datatype_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Field key.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[A-Za-z0-9_]+",
                            "example": "height_architectural"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "community"
                ],
                "summary": "Update a data field.",
                "description": "Changes catalog columns of one field: names, object types, class,\nformat, importance, bounds, flags. Administrators, from a signed-in\nsession.",
                "operationId": "put_api_datatype_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[a-z][a-z0-9_]+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "description": "Any column of `POST /datatypes`.",
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/message/{id}": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "Get a message.",
                "description": "A single message for editorial tools. Messages are the shared substrate\nunder the forum and comments attached to structures and definitions.",
                "operationId": "get_api_message_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Message id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/messages": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "List messages.",
                "description": "Editorial message records, filterable by category, thread, author, or\nthe structure or definition they are attached to.",
                "operationId": "get_api_messages_list",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/From"
                    },
                    {
                        "$ref": "#/components/parameters/PageSize"
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "keyword",
                        "in": "query",
                        "description": "Full-text filter.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "category_id",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "category_key",
                        "in": "query",
                        "description": "Category by slug.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "thread_id",
                        "in": "query",
                        "description": "Messages in one thread.",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "author_id",
                        "in": "query",
                        "description": "Messages by one member.",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "linked_object_id",
                        "in": "query",
                        "description": "Comments attached to this structure or other object.",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "linked_definition_objectid",
                        "in": "query",
                        "description": "Comments attached to this Definition ObjectID.",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/messagecategory/{id}": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "Get a message category.",
                "description": "One category of the editorial message system.",
                "operationId": "get_api_messagecategory_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Message category id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/messagecategories": {
            "get": {
                "tags": [
                    "community"
                ],
                "summary": "List message categories.",
                "description": "Every category of the editorial message system, including forum boards.",
                "operationId": "get_api_messagecategories_list",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/award": {
            "post": {
                "tags": [
                    "award"
                ],
                "summary": "Create an award.",
                "description": "SKYDB Awards honour the most significant tall buildings completed in a\ngiven year; winners are chosen by community vote. Administrators and\nsenior editors only.",
                "operationId": "post_api_award_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "description": "Award fields, title, year, description, linked structures.",
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/award/{id}": {
            "put": {
                "tags": [
                    "award"
                ],
                "summary": "Update an award.",
                "description": "Administrators and senior editors only.",
                "operationId": "put_api_award_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Award id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "description": "Fields to change.",
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "award"
                ],
                "summary": "Delete an award.",
                "description": "Soft delete. Administrators and senior editors only.",
                "operationId": "delete_api_award_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Award id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/channels": {
            "get": {
                "tags": [
                    "channel"
                ],
                "summary": "List channels.",
                "description": "Channels are the editorial groupings a structure can belong to. They\ninclude the tall-building classes Tall Buildings, Skyscrapers and\nSupertall. Channel membership, not a height threshold, determines the\nranking counts, so fetch the ids here rather than hardcoding them.",
                "operationId": "get_api_channels_list",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/channels/search": {
            "get": {
                "tags": [
                    "channel"
                ],
                "summary": "Search channels (typeahead).",
                "description": "Name lookup over the channel list, for pickers.",
                "operationId": "get_api_channels_search",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Search text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/channel/{id}": {
            "get": {
                "tags": [
                    "channel"
                ],
                "summary": "Get a channel.",
                "description": "The channel's name, key and intro text. To list its members, call\n`GET /structures?channel={id}`.",
                "operationId": "get_api_channel_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Channel id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "channel"
                ],
                "summary": "Create or update a channel.",
                "description": "Post to `id=0` to create, to an existing id to update. Administrators\nand senior editors only.",
                "operationId": "put_api_channel_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Channel id, or `0` to create.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "key": {
                                        "description": "Stable slug used in URLs.",
                                        "type": "string"
                                    },
                                    "intro": {
                                        "description": "Intro text for the channel page.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "channel"
                ],
                "summary": "Hide a channel.",
                "description": "Marks the channel invisible instead of deleting it. Its membership\nrecords stay intact, so ranking history is not rewritten.\nAdministrators and senior editors only.",
                "operationId": "delete_api_channel_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Channel id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/collections": {
            "get": {
                "tags": [
                    "collection"
                ],
                "summary": "List public Collections.",
                "description": "Collections are user-curated sets of Objects. Only public Collections\nappear here; use `GET /collections/mine` for your own.",
                "operationId": "get_api_collections_list",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/collection/{id}": {
            "get": {
                "tags": [
                    "collection"
                ],
                "summary": "Get one Collection.",
                "description": "Public Collections are readable by everyone, member-visible Collections\nby signed-in SKYDB accounts, and private Collections by their owner or a\nsenior editor. Deleted and inaccessible Collections both return 404.",
                "operationId": "get_api_collection_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Collection ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "collection"
                ],
                "summary": "Create or edit a Collection.",
                "description": "Post to `id=0` to create, to an existing id to rename. Creating is\nrestricted to administrators and senior editors; an existing Collection\ncan also be edited by its owner. The response carries the Collection's\ncanonical URL.",
                "operationId": "put_api_collection_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Collection ObjectID, or `0` to create.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "visibility": {
                                        "type": "string",
                                        "default": "private",
                                        "enum": [
                                            "private",
                                            "members",
                                            "public"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "collection"
                ],
                "summary": "Delete a Collection.",
                "description": "Sets the Collection's independent deleted status without changing its\nvisibility. Owner, senior editors and administrators.",
                "operationId": "delete_api_collection_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Collection ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/collections/mine": {
            "get": {
                "tags": [
                    "collection"
                ],
                "summary": "List your own Collections.",
                "description": "Every Collection belonging to the signed-in member, regardless of\nwhether its visibility is public, members, or private.\nPass `objectid` to have each row carry a `contains_object` flag, that\nis how an \"Add to Collection\" menu shows which lists an item is already\non, in one request instead of one per Collection.",
                "operationId": "get_api_collections_mine",
                "parameters": [
                    {
                        "name": "objectid",
                        "in": "query",
                        "description": "ObjectID to test membership for. Each returned Collection gains a `contains_object` flag.",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "object_ids",
                        "in": "query",
                        "description": "Comma-separated ObjectIDs whose membership state should be summarized.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "assignment_picker",
                        "in": "query",
                        "description": "Set to true for an Add to Collection picker; limits results to public or private writable Collections.",
                        "schema": {
                            "type": "boolean",
                            "default": false
                        }
                    },
                    {
                        "name": "offset",
                        "in": "query",
                        "description": "Zero-based Collection offset.",
                        "schema": {
                            "type": "integer",
                            "default": 0,
                            "minimum": 0
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Collections per page.",
                        "schema": {
                            "type": "integer",
                            "default": 20,
                            "maximum": 50,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/collections/search": {
            "get": {
                "tags": [
                    "collection"
                ],
                "summary": "Search Collections (typeahead).",
                "description": "Name lookup for Object search: non-empty public Collections plus the\nsigned-in account's own non-empty Collections.",
                "operationId": "get_api_collections_search",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Search text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/award/{year}/vote/{objectid}": {
            "post": {
                "tags": [
                    "award",
                    "content"
                ],
                "summary": "Vote for a nominated building, or take that vote back.",
                "description": "Open to members who have entered 10 buildings or more, while the\naward's voting period runs, for at most three buildings per award. The\nballot is the nominated list: a building nobody nominated is refused.",
                "operationId": "post_api_award_vote",
                "parameters": [
                    {
                        "name": "year",
                        "in": "path",
                        "description": "Award year.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d{4}"
                        }
                    },
                    {
                        "name": "objectid",
                        "in": "path",
                        "description": "The nominated building.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "award",
                    "content"
                ],
                "summary": "Vote for a nominated building, or take that vote back.",
                "description": "Open to members who have entered 10 buildings or more, while the\naward's voting period runs, for at most three buildings per award. The\nballot is the nominated list: a building nobody nominated is refused.",
                "operationId": "delete_api_award_vote",
                "parameters": [
                    {
                        "name": "year",
                        "in": "path",
                        "description": "Award year.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d{4}"
                        }
                    },
                    {
                        "name": "objectid",
                        "in": "path",
                        "description": "The nominated building.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/collection/{id}/object/{objectid}": {
            "post": {
                "tags": [
                    "collection"
                ],
                "summary": "Add an Object to a Collection.",
                "description": "Idempotent, adding something already on the list succeeds and changes\nnothing. You can only write to your own Collections.",
                "operationId": "post_api_collection_add_object",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Collection ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "objectid",
                        "in": "path",
                        "description": "Object ID to add.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "collection"
                ],
                "summary": "Remove an Object from a Collection.",
                "description": "Removes the Object from the Collection. You can only write to your own\nCollections.",
                "operationId": "delete_api_collection_remove_object",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Collection ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "objectid",
                        "in": "path",
                        "description": "Object ID to remove.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/collection/{id}/objects": {
            "post": {
                "tags": [
                    "collection"
                ],
                "summary": "Add up to 50 Objects to one Collection in one indexed batch.",
                "operationId": "post_api_collection_add_objects",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Destination Collection ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "object_ids"
                                ],
                                "properties": {
                                    "object_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer",
                                            "format": "int64"
                                        },
                                        "maxItems": 50
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "collection"
                ],
                "summary": "Remove up to 50 Objects from one Collection in one indexed batch.",
                "operationId": "delete_api_collection_remove_objects",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Collection ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "object_ids"
                                ],
                                "properties": {
                                    "object_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer",
                                            "format": "int64"
                                        },
                                        "maxItems": 50
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/collections/retire-unqualified": {
            "post": {
                "tags": [
                    "content"
                ],
                "summary": "Retire the Collections that fail the catalog retention rule.",
                "description": "Kept: public Collections, and non-public ones holding at least one live\nObject. In both cases the owning account must exist, be active and not\nbe deleted. Everything else is soft-deleted, the same status a single\ndelete sets. Its CollectionItem Objects are retired in the same Object\nmutation so no active connection can point to a retired Collection.\n\nThe rule is evaluated in the database, so this endpoint and a single\ndelete cannot disagree. Administrators only.",
                "operationId": "post_api_collections_retire_unqualified",
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "How many rows to retire in this call (1-50000, default 1000).",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "dry_run",
                        "in": "query",
                        "description": "Report what would be retired without writing.",
                        "required": false,
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/recognitions": {
            "get": {
                "tags": [
                    "recognition"
                ],
                "summary": "List recognitions.",
                "description": "Awards, prizes and honors a structure can hold. This includes SKYDB's own awards as\nwell as external ones. To list the holders of one, call\n`GET /structures?recognition={id}`.",
                "operationId": "get_api_recognitions_list",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/recognitions/search": {
            "get": {
                "tags": [
                    "recognition"
                ],
                "summary": "Search recognitions (typeahead).",
                "description": "Name lookup across awards, certificates and distinctions. Recognitions\nare catalog data and public, so there is nothing to gate. By contrast,\n`GET /collections/search` hides other members' private lists.",
                "operationId": "get_api_recognitions_search",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Search text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/recognition/{id}": {
            "put": {
                "tags": [
                    "recognition"
                ],
                "summary": "Create or rename a recognition.",
                "description": "Post to `id=0` to create. Creating is restricted to administrators and\nsenior editors; an existing row can also be edited by its owner.",
                "operationId": "put_api_recognition_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Recognition id, or `0` to create.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "recognition_type": {
                                        "description": "Category id, e.g. `recognition_type.1.1`.",
                                        "type": "string"
                                    },
                                    "objecttypeid": {
                                        "description": "Attachable object types: `structure` and/or `company`.",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "selectable": {
                                        "type": "boolean"
                                    },
                                    "showcategory": {
                                        "type": "boolean"
                                    },
                                    "recognition_url": {
                                        "type": "string"
                                    },
                                    "accountid": {
                                        "description": "Owner / setup account. Admin and senior editors only; ignored for other callers.",
                                        "type": "integer",
                                        "format": "int64"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "recognition"
                ],
                "summary": "Delete a recognition.",
                "description": "Soft delete. Owner, senior editors and administrators.",
                "operationId": "delete_api_recognition_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Recognition id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/company": {
            "post": {
                "tags": [
                    "company"
                ],
                "summary": "Create a company.",
                "description": "Adds an architecture practice, developer, contractor or engineering firm.\nSearch first, companies are matched to structures by identity, and a\nduplicate firm splits one portfolio across two records.\n\n`company_start` and `company_end` bound the firm's existence; a\nsuccessor practice is a separate company, not a rename.",
                "operationId": "post_api_company_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name"
                                ],
                                "properties": {
                                    "name": {
                                        "description": "Company name in its own language.",
                                        "type": "string"
                                    },
                                    "name_en": {
                                        "description": "English name, where it differs.",
                                        "type": "string"
                                    },
                                    "companytextshortform": {
                                        "description": "Short public description.",
                                        "type": "string"
                                    },
                                    "companytexthidden": {
                                        "description": "Internal notes, not published.",
                                        "type": "string"
                                    },
                                    "url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "phone": {
                                        "type": "string"
                                    },
                                    "fax": {
                                        "type": "string"
                                    },
                                    "company_start": {
                                        "description": "Year founded.",
                                        "type": "integer"
                                    },
                                    "company_end": {
                                        "description": "Year dissolved, if it no longer exists.",
                                        "type": "integer"
                                    },
                                    "parent_id": {
                                        "description": "Parent company, for subsidiaries and branch offices.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "cityid": {
                                        "description": "City the company is based in.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "address": {
                                        "description": "Source address text. Requires address_language whenever supplied.",
                                        "type": "string"
                                    },
                                    "address_language": {
                                        "type": "string",
                                        "pattern": "^[a-z]{2,3}$",
                                        "example": "ko"
                                    },
                                    "postcode": {
                                        "type": "string"
                                    },
                                    "lat": {
                                        "description": "Optional WGS84 pinpoint latitude; supply with lon.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "lon": {
                                        "description": "Optional WGS84 pinpoint longitude; supply with lat.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/company/{id}": {
            "get": {
                "tags": [
                    "company"
                ],
                "summary": "Get a company.",
                "description": "The firm's record, names, contact details, city and address, founding\nand dissolution years, and its parent company where it is a subsidiary\nor branch. For its portfolio call `GET /structures?company={id}`.",
                "operationId": "get_api_company_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Company id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            },
            "put": {
                "tags": [
                    "company"
                ],
                "summary": "Update a company.",
                "description": "Send only the fields you are changing. Same field set as the create call.\nOwner, senior editors and administrators.",
                "operationId": "put_api_company_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Company id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "description": "Any subset of the company fields.",
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "company"
                ],
                "summary": "Delete a company.",
                "description": "Soft delete. Its links to structures are retired rather than erased, so\nthe record of who built what survives. Owner, senior editors and\nadministrators.",
                "operationId": "delete_api_company_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Company id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/company/{id}/smart-addresses": {
            "get": {
                "tags": [
                    "company"
                ],
                "summary": "List a company's smart addresses.",
                "description": "The company's office addresses resolved against the street data, in the\nsame shape as a structure's smart addresses.",
                "operationId": "get_api_company_smart_addresses",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Company id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/company/{id}/upload": {
            "get": {
                "tags": [
                    "content"
                ],
                "summary": "Company Object Tool Upload pane.",
                "operationId": "get_api_company_upload_pane",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/companies/search": {
            "get": {
                "tags": [
                    "company"
                ],
                "summary": "Search companies (typeahead).",
                "description": "Name lookup across companies. Use it before creating one, so the same\nfirm does not end up in the database twice under two spellings.",
                "operationId": "get_api_companies_search",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Search text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/webtext": {
            "get": {
                "tags": [
                    "content"
                ],
                "summary": "List webtexts.",
                "description": "Webtexts are shared application text used by frontend interfaces,\nbackend responses, emails, system messages, and generated content,\nkeyed by a stable identifier and stored per language. The response is\npaginated; `language` changes the displayed translation status and\n`missing=true` limits the result to incomplete webtexts. Access is\nrestricted to editors, senior editors, and administrators.",
                "operationId": "get_api_webtext_list",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Filter by key or text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "pagesize",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offset",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "language",
                        "in": "query",
                        "description": "Target language code used for translation status.",
                        "schema": {
                            "type": "string",
                            "example": "de"
                        }
                    },
                    {
                        "name": "missing",
                        "in": "query",
                        "description": "Return rows missing the selected language, or any language when no target language is selected.",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "content"
                ],
                "summary": "Create a webtext.",
                "description": "Idempotent on `id2`: posting an existing key returns the existing row\ninstead of creating a second one, so a deploy that registers its strings\ncan run repeatedly. The new text is available to readers immediately.\nAccess is restricted to editors, senior editors, and administrators.",
                "operationId": "post_api_webtext_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "id2"
                                ],
                                "properties": {
                                    "id2": {
                                        "description": "Stable string key. Re-posting an existing key is a no-op.",
                                        "type": "string"
                                    },
                                    "translations": {
                                        "description": "Text per language, keyed by ISO 639-1 code.",
                                        "type": "object",
                                        "example": {
                                            "en": "Save",
                                            "de": "Speichern"
                                        }
                                    },
                                    "translationhint": {
                                        "description": "Context note for translators.",
                                        "type": "string"
                                    },
                                    "importantfortranslation": {
                                        "description": "Flag as priority for the translation queue.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/webtext/list": {
            "get": {
                "tags": [
                    "content"
                ],
                "summary": "List webtexts.",
                "description": "Webtexts are shared application text used by frontend interfaces,\nbackend responses, emails, system messages, and generated content,\nkeyed by a stable identifier and stored per language. The response is\npaginated; `language` changes the displayed translation status and\n`missing=true` limits the result to incomplete webtexts. Access is\nrestricted to editors, senior editors, and administrators.",
                "operationId": "get_api_webtext_list_legacy",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Filter by key or text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "pagesize",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "offset",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "language",
                        "in": "query",
                        "description": "Target language code used for translation status.",
                        "schema": {
                            "type": "string",
                            "example": "de"
                        }
                    },
                    {
                        "name": "missing",
                        "in": "query",
                        "description": "Return rows missing the selected language, or any language when no target language is selected.",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/webtext/{id}": {
            "get": {
                "tags": [
                    "content"
                ],
                "summary": "Get a webtext.",
                "description": "One interface string with every language it has been translated into,\nplus the translator hint. Missing languages are absent rather than\nempty, so you can see what still needs work. Access is restricted to\neditors, senior editors, and administrators.",
                "operationId": "get_api_webtext_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Webtext row id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "content"
                ],
                "summary": "Save a webtext.",
                "description": "Writes translations for one string. Only the languages you send are\ntouched; omitting a language leaves its existing translation alone.\nValues equal to the English source are cleared so normal English fallback\napplies. Changes are available to readers immediately. Access is restricted\nto editors, senior editors, and administrators.",
                "operationId": "put_api_webtext_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Webtext row id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "translations": {
                                        "description": "Text per language, keyed by ISO 639-1 code. Unlisted languages are left untouched.",
                                        "type": "object",
                                        "example": {
                                            "en": "Save",
                                            "de": "Speichern"
                                        }
                                    },
                                    "translationhint": {
                                        "description": "Context note for translators.",
                                        "type": "string"
                                    },
                                    "importantfortranslation": {
                                        "description": "Flag as priority for the translation queue.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "content"
                ],
                "summary": "Soft-delete a webtext.",
                "description": "Marks the text as deleted instead of removing it permanently. Access is\nrestricted to editors, senior editors, and administrators.",
                "operationId": "delete_api_webtext_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Webtext row id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/contracts": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "operationId": "post_api_contract_create",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/contracts/{token}/signers": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "operationId": "post_api_contract_add_signer",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/contracts/{token}/sign": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "operationId": "post_api_contract_sign",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/contracts/{token}/signed-pdf": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "operationId": "post_api_contract_signed_pdf",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/contracts/{token}/email-document": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "operationId": "post_api_contract_email_document",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/contracts/{token}/documents/{documentId}": {
            "get": {
                "tags": [
                    "commerce"
                ],
                "operationId": "get_api_contract_document",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "documentId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Stored immutable PDF."
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/contracts/{token}/send-quote": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "operationId": "post_api_contract_send_quote",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/contracts/{token}/confirm": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "operationId": "post_api_contract_confirm",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/contracts/{token}/reject": {
            "post": {
                "tags": [
                    "commerce"
                ],
                "operationId": "post_api_contract_reject",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/data/retire": {
            "post": {
                "tags": [
                    "internal"
                ],
                "summary": "Retire many data rows.",
                "description": "The batch form of `DELETE /data/{id}`: up to 100 row ids with one\nreason, each retired on its own. The response lists one result per\nid; `data.failed` counts the rows that were not retired.",
                "operationId": "post_api_data_retire_batch",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "ids",
                                    "reason"
                                ],
                                "properties": {
                                    "ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer",
                                            "format": "int64"
                                        },
                                        "maxItems": 100
                                    },
                                    "reason": {
                                        "description": "Why these values are retired; recorded on every row.",
                                        "type": "string",
                                        "maxLength": 150
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/data/{id}/infobox": {
            "get": {
                "tags": [
                    "internal"
                ],
                "operationId": "get_api_data_infobox",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[1-9]\\d*"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/datasources/frequent": {
            "get": {
                "tags": [
                    "internal"
                ],
                "summary": "Return the current account's most frequently used Data sources.",
                "operationId": "get_api_datasources_frequent",
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 5,
                            "maximum": 8
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/error-subscription": {
            "post": {
                "tags": [
                    "errors"
                ],
                "summary": "Subscribe to an error's resolution.",
                "description": "Lets a visitor who hit an error ask to be told when it is fixed. The\n`fingerprint` groups identical errors, so everyone affected by the same\nfault is notified together.\n\n`website` is a honeypot: it must stay empty. A filled one gets a\ncheerful `200` with `subscribed: false`, because a bot that sees an\nerror simply retries.",
                "operationId": "post_api_error_subscription",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "required": [
                                    "email",
                                    "fingerprint"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "fingerprint": {
                                        "description": "Error or service-incident fingerprint from the error page, 4 to 32 hex characters.",
                                        "type": "string"
                                    },
                                    "request_id": {
                                        "description": "The failing request id.",
                                        "type": "string"
                                    },
                                    "url": {
                                        "description": "Where the error happened.",
                                        "type": "string"
                                    },
                                    "website": {
                                        "description": "Honeypot. Must be empty.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Subscribed, or silently ignored when the honeypot was filled."
                    },
                    "400": {
                        "description": "Invalid email or fingerprint."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/languages/objects/migration": {
            "get": {
                "tags": [
                    "internal"
                ],
                "operationId": "get_api_language_object_migrate_inventory",
                "responses": {
                    "200": {
                        "description": "Cursor page of legacy Language ids and Object links."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/languages/objects/migration/{id}": {
            "post": {
                "tags": [
                    "internal"
                ],
                "operationId": "post_api_language_object_migrate_create",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Preview or create one Language Object."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/languages/objects": {
            "post": {
                "tags": [
                    "internal"
                ],
                "operationId": "post_api_language_object_create",
                "responses": {
                    "200": {
                        "description": "New Language Object and flat Language projection."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/map/structures": {
            "get": {
                "tags": [
                    "map"
                ],
                "summary": "Get structure pins in a viewport.",
                "description": "Every structure whose pinpoint falls inside the bounding box, as map\npins with the color and glyph the map draws them with. Capped at 2000\npins per call. A denser viewport returns the top of the sort order, so\npass a `sort` that matches what you want to survive the cap.\n\n**Members only** (the whole /map/* group is, since 2026-08-20).\nMetered on its own `map` budget rather than the read quotas, so\npanning does not exhaust a client's normal allowance.",
                "operationId": "get_api_map_structures",
                "parameters": [
                    {
                        "name": "n",
                        "in": "query",
                        "description": "North edge of the bounding box (latitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 50.15
                        }
                    },
                    {
                        "name": "s",
                        "in": "query",
                        "description": "South edge (latitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 50.08
                        }
                    },
                    {
                        "name": "e",
                        "in": "query",
                        "description": "East edge (longitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 8.72
                        }
                    },
                    {
                        "name": "w",
                        "in": "query",
                        "description": "West edge (longitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 8.62
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "description": "Which structures win when the 2000-pin cap bites, e.g. by height.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "pinstyle",
                        "in": "query",
                        "description": "Pin rendering variant.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "with_boundary",
                        "in": "query",
                        "description": "Also return each structure's footprint polygon where one is stored.",
                        "required": false,
                        "schema": {
                            "type": "boolean",
                            "default": false
                        }
                    },
                    {
                        "name": "zoom",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "tiers",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": ""
                        }
                    },
                    {
                        "name": "region",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "channel",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "company",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "recognition",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "collection",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "street",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "account",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "empty",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Rendered HTML fragment.",
                        "content": {
                            "text/html": {}
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/map/structure-boundaries": {
            "get": {
                "tags": [
                    "map"
                ],
                "summary": "Get structure footprints in a viewport.",
                "description": "The building footprint polygons inside the bounding box. Pass `id` to\nload one structure's footprint instead of a viewport. That is how the\nfootprint editor pre-loads an existing shape. Members only.",
                "operationId": "get_api_map_structure_boundaries",
                "parameters": [
                    {
                        "name": "id",
                        "in": "query",
                        "description": "Single structure id. When given, the bounding box is ignored.",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "n",
                        "in": "query",
                        "description": "North edge (latitude).",
                        "required": false,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "s",
                        "in": "query",
                        "description": "South edge (latitude).",
                        "required": false,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "e",
                        "in": "query",
                        "description": "East edge (longitude).",
                        "required": false,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "w",
                        "in": "query",
                        "description": "West edge (longitude).",
                        "required": false,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "tiers",
                        "in": "query",
                        "description": "Restrict to certain structure tiers.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": ""
                        }
                    },
                    {
                        "name": "pinstyle",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "",
                            "enum": [
                                "",
                                "icon",
                                "photo",
                                "dot",
                                "facts"
                            ]
                        }
                    },
                    {
                        "name": "with_boundary",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": ""
                        }
                    },
                    {
                        "name": "zoom",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "region",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "channel",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "company",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "recognition",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "collection",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "street",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "account",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "empty",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/map/regions": {
            "get": {
                "tags": [
                    "map"
                ],
                "summary": "Get region pins in a viewport.",
                "description": "Place markers inside the bounding box. `zoom` selects which tiers are\nsensible to draw. Pass `region` to scope the result to one place, a\nviewport over China scoped to China will not leak in Mongolian cities\nthat happen to fall inside the box.\n\nMembers only. The four broad tiers (countries, states, counties,\nmetro areas) are additionally restricted to senior editors and\nadministrators.",
                "operationId": "get_api_map_regions",
                "parameters": [
                    {
                        "name": "n",
                        "in": "query",
                        "description": "North edge (latitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "s",
                        "in": "query",
                        "description": "South edge (latitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "e",
                        "in": "query",
                        "description": "East edge (longitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "w",
                        "in": "query",
                        "description": "West edge (longitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "zoom",
                        "in": "query",
                        "description": "Current map zoom level. Decides which tiers are returned.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "region",
                        "in": "query",
                        "description": "Scope the result to this region id and its descendants.",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": ""
                        }
                    },
                    {
                        "name": "pinstyle",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "",
                            "enum": [
                                "",
                                "icon",
                                "photo",
                                "dot",
                                "facts"
                            ]
                        }
                    },
                    {
                        "name": "with_boundary",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": ""
                        }
                    },
                    {
                        "name": "tiers",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": ""
                        }
                    },
                    {
                        "name": "channel",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "company",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "recognition",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "collection",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "street",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "account",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "empty",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/map/region-boundaries": {
            "get": {
                "tags": [
                    "map"
                ],
                "summary": "Get region boundaries in a viewport.",
                "description": "Boundary outlines for the regions in the bounding box. The geometry is\n**level-of-detail simplified against `zoom`**: a country-level view gets\na coarse outline, a street-level view the fine one. Always send the zoom\nyou are actually rendering at. The full-detail geometry of a large\ncountry is tens of megabytes.\n\nMembers only, with the same tier restrictions as `GET /map/regions`.",
                "operationId": "get_api_map_region_boundaries",
                "parameters": [
                    {
                        "name": "n",
                        "in": "query",
                        "description": "North edge (latitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "s",
                        "in": "query",
                        "description": "South edge (latitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "e",
                        "in": "query",
                        "description": "East edge (longitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "w",
                        "in": "query",
                        "description": "West edge (longitude).",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "zoom",
                        "in": "query",
                        "description": "Current map zoom. Selects the boundary detail level, low zoom returns a coarse outline.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 8
                        }
                    },
                    {
                        "name": "region",
                        "in": "query",
                        "description": "Scope the result to this region id and its descendants.",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": ""
                        }
                    },
                    {
                        "name": "pinstyle",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "",
                            "enum": [
                                "",
                                "icon",
                                "photo",
                                "dot",
                                "facts"
                            ]
                        }
                    },
                    {
                        "name": "with_boundary",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": ""
                        }
                    },
                    {
                        "name": "tiers",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": ""
                        }
                    },
                    {
                        "name": "channel",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "company",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "recognition",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "collection",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "street",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "account",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 0
                        }
                    },
                    {
                        "name": "empty",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/map/structures-in-area": {
            "post": {
                "tags": [
                    "map"
                ],
                "summary": "Find structures inside a drawn polygon.",
                "description": "Lasso selection: post a polygon and get back every structure whose\npinpoint falls inside it. Used on the map to pick the members of a new\ncomplex.",
                "operationId": "post_api_map_structures_in_area",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "polygon"
                                ],
                                "properties": {
                                    "polygon": {
                                        "description": "Closed ring of `[lat, lon]` pairs.",
                                        "type": "array",
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "number",
                                                "format": "double"
                                            }
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/map/search-fields": {
            "get": {
                "tags": [
                    "map"
                ],
                "summary": "Get the map filter definitions.",
                "description": "The filter panel's field catalog: which facets exist, their possible\nvalues and labels in the request language. Fetch this instead of\nhardcoding status or structural-form codes, which change over time.\nMembers only.",
                "operationId": "get_api_map_search_fields",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/map/boundary": {
            "get": {
                "tags": [
                    "map"
                ],
                "summary": "Get a region's boundary as GeoJSON.",
                "description": "The stored full-detail boundary for one region, for editing. For\nrendering a map use `GET /map/region-boundaries`, which serves a\nzoom-appropriate simplification instead of the full geometry.\nMembers only.",
                "operationId": "get_api_map_boundary",
                "parameters": [
                    {
                        "name": "region_id",
                        "in": "query",
                        "description": "Region id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "map"
                ],
                "summary": "Delete a region boundary data row.",
                "description": "This retires the currently visible `boundary` data row and clears its\nPostGIS projection. Administrators and the account that authored that\nexact boundary version may perform the operation. A reason is required\nand retained with the retired data row.",
                "operationId": "delete_api_map_boundary_delete",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "region_id",
                                    "reason"
                                ],
                                "properties": {
                                    "region_id": {
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "reason": {
                                        "type": "string",
                                        "maxLength": 150
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "A region id and a reason of at most 150 characters are required."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/map/save_boundary": {
            "post": {
                "tags": [
                    "map"
                ],
                "summary": "Save a region's boundary.",
                "description": "Replaces the stored boundary with the posted GeoJSON. The geometry is\nvalidated and normalised to a multipolygon before it is written; a\nself-intersecting ring is repaired rather than stored, because an\ninvalid polygon silently breaks every point-in-region lookup that\ndepends on it.",
                "operationId": "post_api_map_save_boundary",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "region_id",
                                    "geojson"
                                ],
                                "properties": {
                                    "region_id": {
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "geojson": {
                                        "description": "Polygon or MultiPolygon geometry.",
                                        "type": "object"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/move_pinpoint": {
            "post": {
                "tags": [
                    "map"
                ],
                "summary": "Move a structure's pinpoint.",
                "description": "Sets the structure's coordinates. This is the drag-and-drop save behind the\nmap. Moving a pin re-derives the structure's whole region chain from\nthe new position, so its city and district can change as a result.",
                "operationId": "post_api_map_move_pinpoint",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "lat",
                                    "lon"
                                ],
                                "properties": {
                                    "lat": {
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "lon": {
                                        "description": "Longitude. `lng` is accepted as a synonym.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/region/{id}/move_pinpoint": {
            "post": {
                "tags": [
                    "map"
                ],
                "summary": "Move a region's center pinpoint.",
                "description": "Sets the marker position for a place. The center is checked against the\nregion's own boundary; a pin far outside it is flagged, with the\ntolerance scaled to the region's size, so a country center may sit far\nfrom its border while a zone center may not.",
                "operationId": "post_api_map_move_region_pinpoint",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/RegionId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "lat",
                                    "lon"
                                ],
                                "properties": {
                                    "lat": {
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "lon": {
                                        "description": "Longitude. `lng` is accepted as a synonym.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/region/{id}/pinpoint": {
            "delete": {
                "tags": [
                    "map"
                ],
                "summary": "Remove a region's pinpoint. The column becomes NULL and the visible\npinpoint data row is superseded, so the region counts as unpinned; the\nearlier positions stay in the data history. Senior permission, like a\nmove. Meant for a point that stands far from the region's own city and\nhas no better candidate: no point beats a wrong one.",
                "operationId": "delete_api_map_clear_region_pinpoint",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/RegionId"
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "reason": {
                                        "description": "Why the point is removed; kept in the data history.",
                                        "type": "string",
                                        "maxLength": 150
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/upload/": {
            "post": {
                "tags": [
                    "file"
                ],
                "summary": "Upload one or more files, including 3D models.",
                "description": "Multipart upload; the file field is `file-data[]`. EXIF orientation is\napplied and the display sizes are generated server-side, so upload the\noriginal rather than a pre-scaled copy.\n\nAttach the result to a structure and set its copyright via\n`POST /file/{id}`.",
                "operationId": "post_api_upload",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "file-data[]": {
                                        "description": "One or more supported files. GLB and OBJ models require model-preview.",
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "binary"
                                        }
                                    },
                                    "model-preview": {
                                        "description": "JPEG preview rendered by the SKYDB client for a GLB or OBJ model.",
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "objectid": {
                                        "type": "integer",
                                        "format": "int64",
                                        "nullable": true
                                    },
                                    "lat_start": {
                                        "description": "Optional OBJ latitude; supply with lng_start.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90,
                                        "nullable": true
                                    },
                                    "lng_start": {
                                        "description": "Optional OBJ longitude; supply with lat_start.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180,
                                        "nullable": true
                                    },
                                    "scale": {
                                        "description": "OBJ placement scale.",
                                        "type": "number",
                                        "format": "double",
                                        "default": 1,
                                        "exclusiveMinimum": true,
                                        "minimum": 0
                                    },
                                    "rotation": {
                                        "description": "OBJ clockwise rotation in degrees.",
                                        "type": "number",
                                        "format": "double",
                                        "default": 0
                                    },
                                    "elevation": {
                                        "description": "OBJ elevation in meters.",
                                        "type": "number",
                                        "format": "double",
                                        "default": 0
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/count": {
            "get": {
                "tags": [
                    "misc"
                ],
                "summary": "Get global counts.",
                "description": "How many structures, regions, companies and files SKYDB holds. Cached;\nmeant for display, not for reconciliation.",
                "operationId": "get_api_count",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/file/{id}": {
            "put": {
                "tags": [
                    "file"
                ],
                "summary": "Update a file.",
                "description": "Sets a file's metadata: caption, copyright holder, license, the\nconnected object and visibility. OBJ files additionally accept their\nmap placement fields and optional coordinates.\n\n**Private files never appear on any public surface**: not in list cards,\nnot as a hero image, not as share metadata. Marking a file private is\nhow you keep it out of public rendering entirely.",
                "operationId": "put_api_file_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "File id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "properties": {
                                    "objectid": {
                                        "description": "Structure or other object the file belongs to.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "isprivate": {
                                        "description": "Keep the file off every public surface.",
                                        "type": "boolean"
                                    },
                                    "lat_start": {
                                        "description": "Optional file latitude.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90,
                                        "nullable": true
                                    },
                                    "lng_start": {
                                        "description": "Optional file longitude.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180,
                                        "nullable": true
                                    },
                                    "scale": {
                                        "description": "OBJ-only placement scale.",
                                        "type": "number",
                                        "format": "double",
                                        "exclusiveMinimum": true,
                                        "minimum": 0
                                    },
                                    "rotation": {
                                        "description": "OBJ-only rotation in degrees.",
                                        "type": "number",
                                        "format": "double"
                                    },
                                    "elevation": {
                                        "description": "OBJ-only elevation in meters.",
                                        "type": "number",
                                        "format": "double"
                                    }
                                },
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "file"
                ],
                "summary": "Update a file.",
                "description": "Sets a file's metadata: caption, copyright holder, license, the\nconnected object and visibility. OBJ files additionally accept their\nmap placement fields and optional coordinates.\n\n**Private files never appear on any public surface**: not in list cards,\nnot as a hero image, not as share metadata. Marking a file private is\nhow you keep it out of public rendering entirely.",
                "operationId": "post_api_file_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "File id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "properties": {
                                    "objectid": {
                                        "description": "Structure or other object the file belongs to.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "isprivate": {
                                        "description": "Keep the file off every public surface.",
                                        "type": "boolean"
                                    },
                                    "lat_start": {
                                        "description": "Optional file latitude.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90,
                                        "nullable": true
                                    },
                                    "lng_start": {
                                        "description": "Optional file longitude.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180,
                                        "nullable": true
                                    },
                                    "scale": {
                                        "description": "OBJ-only placement scale.",
                                        "type": "number",
                                        "format": "double",
                                        "exclusiveMinimum": true,
                                        "minimum": 0
                                    },
                                    "rotation": {
                                        "description": "OBJ-only rotation in degrees.",
                                        "type": "number",
                                        "format": "double"
                                    },
                                    "elevation": {
                                        "description": "OBJ-only elevation in meters.",
                                        "type": "number",
                                        "format": "double"
                                    }
                                },
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "file",
                    "misc"
                ],
                "summary": "Retire a file.",
                "description": "Marks the record deleted with a reason, the retiring account and the\ndate; the record leaves every page and count. Nothing on disk is\nremoved. The uploader may retire their own files; administrators and\nautomation tokens any file.",
                "operationId": "delete_api_file_retire",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "File id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "description": "Why the file is retired; recorded on the record.",
                                        "type": "string",
                                        "maxLength": 150
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/file/{id}/rotate-left": {
            "post": {
                "tags": [
                    "file"
                ],
                "summary": "Rotate a photo 90 degrees counter-clockwise.",
                "description": "Physically rotates the original, updates dimensions, orientation, EXIF\norientation and byte size, then removes every cached thumbnail variant.\nRequires the file's uploader, a senior, or an administrator.",
                "operationId": "post_api_file_rotate_left",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "File id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/file/{id}/rotate-right": {
            "post": {
                "tags": [
                    "file"
                ],
                "summary": "Rotate a photo 90 degrees clockwise.",
                "description": "Physically rotates the original, updates dimensions, orientation, EXIF\norientation and byte size, then removes every cached thumbnail variant.\nRequires the file's uploader, a senior, or an administrator.",
                "operationId": "post_api_file_rotate_right",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "File id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/key-image/{entity}/{id}": {
            "get": {
                "tags": [
                    "file"
                ],
                "summary": "Get the render-ready key image for one entity.",
                "description": "Returns the same compact image data used by infoboxes and search results.\nRegion records fall back to their panorama when no normal key image is\navailable. Set `variant=panorama` to request the Region panorama explicitly.\n`building` is accepted as an alias for `structure`.\n\nA visible entity without an image returns `key_image: null`. A missing,\ninactive or non-public entity returns 404.",
                "operationId": "get_api_entity_key_image",
                "parameters": [
                    {
                        "name": "entity",
                        "in": "path",
                        "description": "Entity type. `building` is an alias for `structure`.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "account|building|collection|company|definition|file|region|street|structure",
                            "enum": [
                                "account",
                                "building",
                                "collection",
                                "company",
                                "definition",
                                "file",
                                "region",
                                "street",
                                "structure"
                            ]
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Entity id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "variant",
                        "in": "query",
                        "description": "Use `panorama` to request a Region panorama explicitly.",
                        "schema": {
                            "type": "string",
                            "default": "default",
                            "enum": [
                                "default",
                                "panorama"
                            ]
                        }
                    }
                ],
                "responses": {
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/file/{id}/rate": {
            "post": {
                "tags": [
                    "file"
                ],
                "summary": "Rate a photo.",
                "description": "One rating per member; posting again replaces the previous one.",
                "operationId": "post_api_file_rate",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "File id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "stars": {
                                        "description": "Half-star increments from 0.5 to 5.",
                                        "type": "number",
                                        "format": "float",
                                        "maximum": 5,
                                        "minimum": 0.5
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/search/all": {
            "get": {
                "tags": [
                    "misc"
                ],
                "summary": "Search across all entities.",
                "description": "One query over structures, regions, streets, companies and files, ranked\nagainst each other. This is the site's main search box.\n\nRanking is size-aware, so a large city outranks a building that happens\nto share its name. Address queries are also understood. A house number\nplus street resolves to the building at that address across different\naddress conventions (`50 Rockefeller Plaza`, `Hauptstra\u00dfe 12`).\n\nAnonymous callers get at most 20 results per call; page one is public,\ndeeper paging needs a session.",
                "operationId": "get_api_search_all",
                "parameters": [
                    {
                        "name": "keyword",
                        "in": "query",
                        "description": "Search text.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "entity",
                        "in": "query",
                        "description": "Restrict to one entity type. `mention` searches Structure, Company and Region for entity mention pickers.",
                        "schema": {
                            "type": "string",
                            "default": "all",
                            "enum": [
                                "all",
                                "mention",
                                "structure",
                                "region",
                                "street",
                                "company",
                                "file"
                            ]
                        }
                    },
                    {
                        "name": "size",
                        "in": "query",
                        "description": "Results per call. Capped at 20 for anonymous callers.",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    },
                    {
                        "$ref": "#/components/parameters/From"
                    },
                    {
                        "name": "language",
                        "in": "query",
                        "description": "Language to rank and label in, ISO 639-1.",
                        "schema": {
                            "type": "string",
                            "default": "en"
                        }
                    },
                    {
                        "name": "include_files",
                        "in": "query",
                        "description": "Include photos in the results.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "jump",
                        "in": "query",
                        "description": "Resolve an unambiguous hit to its target URL, for \"I feel lucky\" navigation.",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/notifications/preferences": {
            "get": {
                "tags": [
                    "notifications"
                ],
                "operationId": "get_api_notification_preferences",
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "notifications"
                ],
                "operationId": "post_api_notification_preference_save",
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/recipients/resolve": {
            "get": {
                "tags": [
                    "notifications"
                ],
                "summary": "Resolve a person, account ID, email address, phone number or Telegram handle for the composer.",
                "operationId": "get_api_notification_recipient_resolve",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Recipient name or communication address.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "422": {
                        "description": "The recipient input is invalid."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/notifications/alerts": {
            "get": {
                "tags": [
                    "notifications"
                ],
                "summary": "List the signed-in account's alerts.",
                "operationId": "get_api_notification_alerts",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "notifications"
                ],
                "summary": "Create one tenant-bound alert for the signed-in account.",
                "operationId": "post_api_notification_alert_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name",
                                    "criteria"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 160
                                    },
                                    "entity_type": {
                                        "type": "string",
                                        "default": "structure",
                                        "enum": [
                                            "structure"
                                        ]
                                    },
                                    "criteria": {
                                        "required": [
                                            "version",
                                            "event",
                                            "delivery",
                                            "where"
                                        ],
                                        "properties": {
                                            "version": {
                                                "type": "integer",
                                                "enum": [
                                                    1
                                                ]
                                            },
                                            "event": {
                                                "type": "string",
                                                "enum": [
                                                    "created",
                                                    "deleted"
                                                ]
                                            },
                                            "delivery": {
                                                "type": "string",
                                                "enum": [
                                                    "automatic",
                                                    "notify"
                                                ]
                                            },
                                            "where": {
                                                "type": "object"
                                            }
                                        },
                                        "type": "object"
                                    },
                                    "priority": {
                                        "type": "string",
                                        "enum": [
                                            "low",
                                            "normal",
                                            "high",
                                            "critical"
                                        ]
                                    },
                                    "frequency": {
                                        "type": "string",
                                        "enum": [
                                            "immediate",
                                            "daily",
                                            "weekly"
                                        ]
                                    },
                                    "enabled": {
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "422": {
                        "description": "Alert validation failed."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/alerts/{id}": {
            "patch": {
                "tags": [
                    "notifications"
                ],
                "summary": "Update one alert owned by the signed-in account and current tenant.",
                "operationId": "patch_api_notification_alert_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name",
                                    "criteria"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 160
                                    },
                                    "entity_type": {
                                        "type": "string",
                                        "default": "structure",
                                        "enum": [
                                            "structure"
                                        ]
                                    },
                                    "criteria": {
                                        "required": [
                                            "version",
                                            "event",
                                            "delivery",
                                            "where"
                                        ],
                                        "properties": {
                                            "version": {
                                                "type": "integer",
                                                "enum": [
                                                    1
                                                ]
                                            },
                                            "event": {
                                                "type": "string",
                                                "enum": [
                                                    "created",
                                                    "deleted"
                                                ]
                                            },
                                            "delivery": {
                                                "type": "string",
                                                "enum": [
                                                    "automatic",
                                                    "notify"
                                                ]
                                            },
                                            "where": {
                                                "type": "object"
                                            }
                                        },
                                        "type": "object"
                                    },
                                    "priority": {
                                        "type": "string",
                                        "enum": [
                                            "low",
                                            "normal",
                                            "high",
                                            "critical"
                                        ]
                                    },
                                    "frequency": {
                                        "type": "string",
                                        "enum": [
                                            "immediate",
                                            "daily",
                                            "weekly"
                                        ]
                                    },
                                    "enabled": {
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "description": "Alert not found."
                    },
                    "422": {
                        "description": "Alert validation failed."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/alerts/{id}/archive": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "summary": "Soft-archive one alert owned by the signed-in account and current tenant.",
                "operationId": "post_api_notification_alert_archive",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/drafts": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "operationId": "post_api_notification_draft_create",
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/drafts/{publicId}": {
            "delete": {
                "tags": [
                    "notifications"
                ],
                "operationId": "delete_api_notification_draft_delete",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "notifications"
                ],
                "operationId": "patch_api_notification_draft_update",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/drafts/{publicId}/archive": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "operationId": "post_api_notification_draft_archive",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/drafts/{publicId}/restore": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "operationId": "post_api_notification_draft_restore",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/drafts/{publicId}/send": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "operationId": "post_api_notification_draft_send",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/{publicId}/read": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "operationId": "post_api_notification_read",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/bulk": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "operationId": "post_api_notification_bulk",
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/{publicId}/archive": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "operationId": "post_api_notification_archive",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/{publicId}": {
            "delete": {
                "tags": [
                    "notifications"
                ],
                "operationId": "delete_api_notification_delete",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "notifications"
                ],
                "operationId": "patch_api_notification_edit",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/{publicId}/restore": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "operationId": "post_api_notification_restore",
                "parameters": [
                    {
                        "name": "publicId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/notifications/webhooks/{tenant}/{id}": {
            "post": {
                "tags": [
                    "notifications"
                ],
                "summary": "Receive a signed message or event from one tenant provider.",
                "operationId": "post_api_notification_provider_webhook",
                "parameters": [
                    {
                        "name": "tenant",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[a-z][a-z0-9_-]{1,63}"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/export/fields/{entity}": {
            "get": {
                "summary": "The fields and formats the dialog offers for one entity.",
                "description": "A search across several object types reports its entity as \"mixed\".\nThere is no field catalog for that, because a Region and a Structure\nshare almost no columns, so the dialog gets the identity fields only and\nthe export writes one file per entity found in the selection.",
                "operationId": "get_api_export_fields",
                "parameters": [
                    {
                        "name": "entity",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/export/coverage": {
            "post": {
                "summary": "How filled the chosen fields are, and what the rows will cost.",
                "description": "The summary asks this before anything is built, so a reader sees that a\ncolumn is empty on every row while they can still untick it, rather than\nafter opening the file (operator 2026-09-12).\n\nIt resolves the selection the same way the export does and then counts in\none aggregation request, so asking costs about as much as one page of\nresults whatever the selection size.",
                "operationId": "post_api_export_coverage",
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/export/price": {
            "post": {
                "summary": "What the export costs, and nothing else.",
                "description": "The price used to ride along with the coverage answer, which aggregates\nover the whole selection: 327 seconds for 9,092 structures, so the\nsummary stood there with no price on it (measured 2026-09-13). Pricing\nneeds one number, the row count, and one page of results already reports\nit, so this route answers in milliseconds however large the selection.\n\nIt also takes `limit`, because the summary lets a reader cap the rows and\nthe figure has to follow what they typed rather than quoting a file they\nare not buying.",
                "operationId": "post_api_export_price",
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/export/preview": {
            "post": {
                "operationId": "post_api_export_preview",
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/export/{entity}": {
            "get": {
                "summary": "The same export addressed by a search rather than a selection.",
                "description": "A script cannot hold a selection descriptor, and a marked selection is a\nmoment rather than a criterion. What a script can hold is the search:\n`GET /api/v1/export/region?keyword=district&format=csv` returns the\ncurrent answer to that search every time it runs, which is what makes it\nusable from a cron job or a spreadsheet that refreshes itself.\n\nAuthenticated like every other API route, so an `sdk` bearer token works\nwhere a browser session does not.",
                "operationId": "get_api_export_query",
                "parameters": [
                    {
                        "name": "entity",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[a-z]+"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/export/objects": {
            "post": {
                "summary": "Builds the file and returns it as a download.",
                "description": "The selection arrives as the list's own descriptor and is resolved\nthrough `ObjectSelectionAction`, the same path Compare objects and\nDelete objects use. `export_objects` is a paged action there, so the\nresolver walks the whole result set in pages and the export carries no\nobject limit of its own.",
                "operationId": "post_api_export_objects",
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structureparent/{id}/view": {
            "get": {
                "tags": [
                    "object-tool"
                ],
                "summary": "Get the StructureParent Connection Object Review tab.",
                "operationId": "get_api_structureparent_view",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/recognitionassignment/{id}/view": {
            "get": {
                "tags": [
                    "object-tool"
                ],
                "summary": "Get the RecognitionAssignment Connection Object Review tab.",
                "operationId": "get_api_recognitionassignment_view",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/{entity}/{id}/timeline": {
            "get": {
                "tags": [
                    "object-tool"
                ],
                "summary": "Get a Company or Region Timeline pane.",
                "operationId": "get_api_entity_timeline",
                "parameters": [
                    {
                        "name": "entity",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "company|region",
                            "enum": [
                                "company",
                                "region"
                            ]
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "object-tool"
                ],
                "summary": "Save a Company or Region Timeline pane.",
                "operationId": "post_api_entity_save_timeline",
                "parameters": [
                    {
                        "name": "entity",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "company|region",
                            "enum": [
                                "company",
                                "region"
                            ]
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "422": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/{entity}/{id}/data": {
            "post": {
                "tags": [
                    "object-tool"
                ],
                "summary": "Create or update an entity's data.",
                "description": "The Object Tool save path for a non-structure entity. Body keys name\nthe fields; core columns enter injected Doctrine stores and data fields\nenter the canonical versioned Data mutation service. The exact owning\nentity projection is refreshed synchronously before the response.\nPost to `id=0` to create; the new id returns as `new_id`.",
                "operationId": "post_api_entity_save_data",
                "parameters": [
                    {
                        "name": "entity",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "street|company|region",
                            "enum": [
                                "street",
                                "company",
                                "region"
                            ]
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Entity id to update, or 0 to create.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "description": "Entity fields keyed by their canonical field names. Available fields depend on the entity path parameter.",
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "description": "Street or Company name. Required when creating those entities.",
                                        "type": "string"
                                    },
                                    "name_en": {
                                        "description": "English Region name, or an optional English Company name.",
                                        "type": "string"
                                    },
                                    "localized_name": {
                                        "description": "Existing entity name in the explicit name_language slot. Used by the multilingual Object Tool editor.",
                                        "type": "string"
                                    },
                                    "name_language": {
                                        "description": "Language slot used for name-family Data fields. Must be a known SKYDB ISO language code.",
                                        "type": "string",
                                        "pattern": "^[a-z]{2,3}$",
                                        "example": "ar"
                                    },
                                    "parent_id": {
                                        "description": "Parent Region, city/district, or Company as defined by the selected entity.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "confirm_not_duplicate": {
                                        "description": "Resubmit with true to create despite duplicate candidates.",
                                        "type": "boolean"
                                    },
                                    "default_source_id": {
                                        "description": "Existing Data Source used by changed fields without an override.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "default_source_valid_from": {
                                        "description": "Default Valid from as YYYY, YYYY-MM, or YYYY-MM-DD.",
                                        "type": "string"
                                    },
                                    "default_source_valid_to": {
                                        "description": "Default Valid to as YYYY, YYYY-MM, or YYYY-MM-DD.",
                                        "type": "string"
                                    },
                                    "source_id": {
                                        "description": "Per-field existing Data Source IDs, keyed by datatypeid.",
                                        "type": "object"
                                    },
                                    "source_details": {
                                        "description": "Per-field source details, keyed by datatypeid or Smart Address row key. Removing a stored value or Smart Address connection requires a new explanation for that field.",
                                        "type": "object"
                                    },
                                    "source_valid_from": {
                                        "description": "Per-field Valid from values, keyed by datatypeid.",
                                        "type": "object"
                                    },
                                    "source_valid_to": {
                                        "description": "Per-field Valid to values, keyed by datatypeid.",
                                        "type": "object"
                                    },
                                    "historical_assertions": {
                                        "description": "Optional per-DataID validity edits. They are validated and versioned atomically with the other fields.",
                                        "type": "array",
                                        "items": {
                                            "$ref": "#/components/schemas/ObjectToolAssertionDraft"
                                        }
                                    }
                                },
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The saved fields and resulting immutable Object version.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ObjectToolWriteEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/object/{id}/versions/compare": {
            "get": {
                "tags": [
                    "internal"
                ],
                "summary": "Compare every recorded version of one Object side by side.",
                "operationId": "get_api_object_versions_compare",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "[1-9]\\d*"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/geo/{scope}": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "Get the world outline (GeoJSON).",
                "description": "Returns a raw `FeatureCollection`, **not** the standard envelope. A geo\nlayer is expected to be GeoJSON you can hand straight to a mapping\nlibrary. The geometry is static and cached hard.",
                "operationId": "get_api_geo_layer_world",
                "parameters": [
                    {
                        "name": "scope",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "world",
                            "enum": [
                                "world"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "GeoJSON FeatureCollection.",
                        "content": {
                            "application/geo+json": {}
                        }
                    },
                    "404": {
                        "description": "No such layer."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/geo/{scope}/{key}": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "Get a country or state outline (GeoJSON).",
                "description": "Same raw-GeoJSON contract as the world layer, scoped to one country or\nstate.",
                "operationId": "get_api_geo_layer_scoped",
                "parameters": [
                    {
                        "name": "scope",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "country|state",
                            "enum": [
                                "country",
                                "state"
                            ]
                        }
                    },
                    {
                        "name": "key",
                        "in": "path",
                        "description": "Region key within the scope, lowercase.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[A-Za-z0-9-]{1,12}",
                            "example": "de"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "GeoJSON FeatureCollection.",
                        "content": {
                            "application/geo+json": {}
                        }
                    },
                    "404": {
                        "description": "No such layer."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/geo/ip-location": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "Locate the calling client.",
                "description": "Approximate location of whoever is making this request, used to open the\nmap somewhere sensible. Public, because it only ever echoes the caller's\n**own** location back. You cannot look up anyone else.",
                "operationId": "get_api_geo_ip_location",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/geocode/reverse": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "Reverse-geocode coordinates.",
                "description": "Turns a point into a place name and address. This is general\ngeocoding against SKYDB's own OpenStreetMap infrastructure, use\n`GET /region/by-coordinates` when you want the SKYDB *region* a point\nfalls in.",
                "operationId": "get_api_geocode_reverse",
                "parameters": [
                    {
                        "name": "lat",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    },
                    {
                        "name": "lon",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/geocode/forward": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "Forward-geocode a place name.",
                "description": "Turns a text query into coordinates, what the map's \"search a location\"\nbox uses. To find SKYDB records rather than places, use\n`GET /search/all`.",
                "operationId": "get_api_geocode_forward",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Place name or address.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/fact/list": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "List an object's facts.",
                "description": "Facts are the short editorial notes shown alongside a record, \"tallest\nbuilding in the city until 1998\", written per language rather than\ntranslated.",
                "operationId": "get_api_fact_list",
                "parameters": [
                    {
                        "name": "objecttype",
                        "in": "query",
                        "description": "Entity kind the facts hang off.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "structure"
                        }
                    },
                    {
                        "name": "objectid",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "lang",
                        "in": "query",
                        "description": "Language to return, ISO 639-1.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/fact": {
            "post": {
                "tags": [
                    "ops"
                ],
                "summary": "Create a fact.",
                "description": "Adds an editorial note to a record. Give a `source`, facts are held to\nthe same sourcing standard as any other value.",
                "operationId": "post_api_fact_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "objecttype",
                                    "objectid",
                                    "html"
                                ],
                                "properties": {
                                    "objecttype": {
                                        "type": "string",
                                        "example": "structure"
                                    },
                                    "objectid": {
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "lang": {
                                        "description": "Language this text is written in.",
                                        "type": "string",
                                        "default": "en"
                                    },
                                    "html": {
                                        "description": "The fact text.",
                                        "type": "string"
                                    },
                                    "source": {
                                        "description": "Where it comes from.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/fact/{id}": {
            "delete": {
                "tags": [
                    "ops"
                ],
                "summary": "Delete a fact.",
                "description": "Soft delete. Authors delete their own facts; administrators can delete\nany.",
                "operationId": "delete_api_fact_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Fact id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "ops"
                ],
                "summary": "Update a fact.",
                "description": "Authors edit their own facts; administrators can edit any.",
                "operationId": "patch_api_fact_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Fact id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "html": {
                                        "description": "Replacement text.",
                                        "type": "string"
                                    },
                                    "lang": {
                                        "type": "string"
                                    },
                                    "source": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/data": {
            "post": {
                "tags": [
                    "ops"
                ],
                "summary": "Write data fields atomically.",
                "description": "Writes several assertions across one Object in one transaction. Either\nevery field lands or none do, and one request produces at most one\nimmutable Object version. Omit `selected` or pass `true` for the ordinary\ncurrent value. Pass `selected=false` with a validity boundary to record an\naccepted historical assertion without replacing the current value.\nTo remove a value, pass its DataID in `data_ref_id` and a new\n`deletion_reason` for that field. An existing source alone is not a reason.",
                "operationId": "post_api_data_write",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "description": "The batch to write: the target object and the fields to set on it.",
                                "required": [
                                    "objectid",
                                    "fields"
                                ],
                                "properties": {
                                    "objectid": {
                                        "description": "The structure, region, company or street to write on.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "default_source": {
                                        "$ref": "#/components/schemas/DataSourceInput"
                                    },
                                    "fields": {
                                        "description": "The fields to set.",
                                        "type": "array",
                                        "items": {
                                            "required": [
                                                "datatypeid"
                                            ],
                                            "properties": {
                                                "datatypeid": {
                                                    "description": "Field id or field name.",
                                                    "type": "string"
                                                },
                                                "value": {
                                                    "description": "The value; null retires the DataID named in data_ref_id when deletion_reason is supplied."
                                                },
                                                "deletion_reason": {
                                                    "description": "Required when removing a value. Explain why that specific value should be removed.",
                                                    "type": "string"
                                                },
                                                "source": {
                                                    "description": "Existing Data Source ID, source name, or a DataSourceInput object; overrides default_source."
                                                },
                                                "language": {
                                                    "description": "ISO 639-1 code for language-dependent fields.",
                                                    "type": "string"
                                                },
                                                "language_default": {
                                                    "description": "Use the language-neutral Default slot instead of inferring English.",
                                                    "type": "boolean"
                                                },
                                                "time_start": {
                                                    "description": "Valid-time start as YYYY, YYYY-MM, or YYYY-MM-DD.",
                                                    "type": "string"
                                                },
                                                "time_anchor": {
                                                    "description": "Date witnessed as YYYY, YYYY-MM, or YYYY-MM-DD. This is not a validity boundary.",
                                                    "type": "string"
                                                },
                                                "time_end": {
                                                    "description": "Valid-time end as YYYY, YYYY-MM, or YYYY-MM-DD.",
                                                    "type": "string"
                                                },
                                                "accuracy": {
                                                    "type": "string"
                                                },
                                                "data_ref_id": {
                                                    "description": "Stable DataID of the assertion being replaced or retired.",
                                                    "type": "integer",
                                                    "format": "int64"
                                                },
                                                "data_org_id": {
                                                    "type": "integer",
                                                    "format": "int64"
                                                },
                                                "selected": {
                                                    "description": "Whether this assertion supplies the ordinary current field value. False requires Valid from or Valid to and does not replace the current value.",
                                                    "type": "boolean",
                                                    "default": true
                                                },
                                                "timeline_temporality": {
                                                    "description": "Assertion temporality for Timeline fields. Defaults to actual.",
                                                    "type": "string",
                                                    "enum": [
                                                        "actual",
                                                        "expected"
                                                    ]
                                                },
                                                "date": {
                                                    "description": "Timeline date alias for time_end, as YYYY, YYYY-MM, or YYYY-MM-DD.",
                                                    "type": "string"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The resulting Object version, normalized assertions, and current selection.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataWriteEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/UnprocessableEntity"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/data/batch": {
            "post": {
                "tags": [
                    "ops"
                ],
                "summary": "Write data fields on many objects.",
                "description": "The batch form of `POST /data` for imports: up to 100 items, each the\nbody `POST /data` takes (`objectid`, `fields`, optional\n`default_source`). A top-level `default_source` applies to every item\nthat names none. Each item is written on its own; one failing item\ndoes not roll back the others. The response lists one result per item\nwith its resulting Object version, stable DataIDs, current selection,\n`ok`, `code`, and field errors. `failed` is the failed-item count.",
                "operationId": "post_api_data_write_batch",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "items"
                                ],
                                "properties": {
                                    "default_source": {
                                        "description": "Applied to every item without its own default_source.",
                                        "type": "object"
                                    },
                                    "items": {
                                        "description": "One `POST /data` body per object.",
                                        "type": "array",
                                        "items": {
                                            "type": "object"
                                        },
                                        "maxItems": 100
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Per-item mutation results; `data.failed` counts the items that did not save.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataWriteBatchEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/object/{id}/recompute-regions": {
            "post": {
                "tags": [
                    "ops"
                ],
                "summary": "Recompute the regions of an object.",
                "description": "Rebuilds the `object_region` links of one structure or company from\nits authoritative facts (`regionid`, pinpoint, parent chain), the way\na save does. Use it after a region was split, merged or re-parented,\ninstead of editing `object_region` by hand. Import and automation\ntokens (the rebuild is attributed to that account).",
                "operationId": "post_api_object_recompute_regions",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Structure or company id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "description": "The object is not an active structure or company."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/{entity}/{id}/smart-addresses": {
            "post": {
                "tags": [
                    "ops"
                ],
                "summary": "Save a smart address.",
                "description": "Attaches a structure or company to a street with a house number range:\n`streetid`, `address_type` (the range kind the address catalog knows),\n`address_start`, optional `address_end` (defaults to the start) and\n`address_extension`. Pass the StreetAddress ObjectID as `connect_id` to\nedit the existing Connection. Signed-in accounts.",
                "operationId": "post_api_object_smart_address_save",
                "parameters": [
                    {
                        "name": "entity",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "structure|company",
                            "enum": [
                                "structure",
                                "company"
                            ]
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "streetid",
                                    "address_type"
                                ],
                                "properties": {
                                    "streetid": {
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "address_type": {
                                        "type": "string"
                                    },
                                    "address_start": {
                                        "type": "string"
                                    },
                                    "address_end": {
                                        "type": "string"
                                    },
                                    "address_extension": {
                                        "type": "string"
                                    },
                                    "connect_id": {
                                        "description": "Existing StreetAddress ObjectID to edit.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "sourceid": {
                                        "description": "Source id recorded on the row.",
                                        "type": "integer"
                                    },
                                    "time_anchor": {
                                        "description": "YYYY, YYYY-MM or YYYY-MM-DD.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/{entity}/{id}/smart-addresses/{connectId}": {
            "delete": {
                "tags": [
                    "ops"
                ],
                "summary": "Retire a smart address.",
                "description": "Retires one StreetAddress Object of a structure or company. Its Object\nVersion history remains available. Signed-in accounts.",
                "operationId": "delete_api_object_smart_address_delete",
                "parameters": [
                    {
                        "name": "entity",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "structure|company",
                            "enum": [
                                "structure",
                                "company"
                            ]
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "connectId",
                        "in": "path",
                        "description": "The StreetAddress ObjectID.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "422": {
                        "description": "The row could not be retired."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/data/{id}": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "Get a data row.",
                "description": "One individual recorded value with its provenance, who set it, when,\nand from which source. `version_member` says whether it belongs to the\ncurrent Object version. `selected=false` identifies an accepted\nhistorical assertion that does not replace the ordinary current value.",
                "operationId": "get_api_data_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Data row id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The Data assertion and its current-version membership state.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataRowEnvelope"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/object/{id}": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "Resolve an object id.",
                "description": "Structures, regions, companies and streets share one id space. Given a\nbare id, this reports which kind it is and returns its record. This is useful\nwhen you hold an id from an audit trail and do not know its type.",
                "operationId": "get_api_object_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Object id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/object/{id}/data": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "Get an object's edit history.",
                "description": "The current Object version's selected and accepted historical\nassertions, with author, timestamp, validity and source. Pass\n`include_deleted=1` as an administrator to include assertions outside\nthe current version as well.\n\nPage one is public; deeper paging needs a session.",
                "operationId": "get_api_object_data",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Object id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/From"
                    },
                    {
                        "$ref": "#/components/parameters/PageSize"
                    },
                    {
                        "name": "datatypeid",
                        "in": "query",
                        "description": "Return one field only.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "language",
                        "in": "query",
                        "description": "Return one language slot only. Use und for the default/no-language slot.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "include_deleted",
                        "in": "query",
                        "description": "Administrator-only: include assertions outside the current Object version.",
                        "required": false,
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Selected and accepted historical assertions in the current Object version.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ObjectDataHistoryEnvelope"
                                }
                            }
                        }
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/object/{id}/rate": {
            "post": {
                "tags": [
                    "ops"
                ],
                "summary": "Compatibility route for Structure ratings addressed by Object ID.",
                "operationId": "post_api_object_rate",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "stars"
                                ],
                                "properties": {
                                    "stars": {
                                        "description": "Half-star increments from 0.5 to 5.",
                                        "type": "number",
                                        "format": "float",
                                        "maximum": 5,
                                        "minimum": 0.5
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "The rating is outside the supported half-star range."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/lookup/{table}": {
            "get": {
                "tags": [
                    "ops"
                ],
                "summary": "Read a lookup table.",
                "description": "The small reference tables behind coded values, region groups, region\ntypes, sources and similar. Which tables are readable is a server-side\nwhitelist; anything not on it is refused.",
                "operationId": "get_api_lookup_table",
                "parameters": [
                    {
                        "name": "table",
                        "in": "path",
                        "description": "Lookup table name. Whitelisted server-side.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[a-z]+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/elasticsearch/index/purge": {
            "post": {
                "tags": [
                    "ops"
                ],
                "summary": "Permanently delete every physical version of an entity already removed\nfrom the cockpit, then delete its orphaned registry rows.",
                "operationId": "post_api_es_index_purge",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "entity": {
                                        "description": "Removed entity whose physical indexes will be deleted.",
                                        "type": "string"
                                    },
                                    "confirm": {
                                        "description": "Must be true.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/pricing/{id}": {
            "post": {
                "tags": [
                    "internal"
                ],
                "summary": "Save every currency of one product in a single request.",
                "operationId": "post_api_pricing_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The prices that were written."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/projectrole/{id}": {
            "delete": {
                "tags": [
                    "internal"
                ],
                "summary": "Retire one ProjectRole Object and its current projections.",
                "operationId": "delete_api_projectrole_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "description": "Explain why this Project Role connection should be removed.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/UnprocessableEntity"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/recognitionassignment/migrate": {
            "post": {
                "tags": [
                    "internal"
                ],
                "operationId": "post_api_recognitionassignment_migrate",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "legacy_data_id"
                                ],
                                "properties": {
                                    "legacy_data_id": {
                                        "type": "integer",
                                        "format": "int64",
                                        "minimum": 1
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/recognitionassignment/{id}": {
            "get": {
                "tags": [
                    "internal"
                ],
                "operationId": "get_api_recognitionassignment_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "minimum": 1,
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "internal"
                ],
                "operationId": "delete_api_recognitionassignment_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "minimum": 1,
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/region/{id}/merge-into/{keeper}": {
            "post": {
                "tags": [
                    "region"
                ],
                "summary": "Merge a region into another.",
                "description": "Retires a duplicate region after re-homing everything it holds: every\nstructure and company is linked to the keeper through the normal\n`regionid` save, every child region gets the keeper as parent, the\nsource's names become aliases of the keeper. No structure is deleted.\nWithout `apply=true` the response is the plan with the counts and\nnothing is written. Both regions must be of the same tier unless\n`allow_group_change=true`. Administrators, senior editors and\nautomation tokens.",
                "operationId": "post_api_region_merge",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "The region that goes away.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "keeper",
                        "in": "path",
                        "description": "The region that stays.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "apply": {
                                        "description": "Write. Default false: dry run.",
                                        "type": "boolean"
                                    },
                                    "alias": {
                                        "description": "Add the source names as aliases of the keeper. Default true.",
                                        "type": "boolean"
                                    },
                                    "allow_group_change": {
                                        "description": "Merge across region tiers.",
                                        "type": "boolean"
                                    },
                                    "comment": {
                                        "description": "Retire comment on the source.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/region/{id}/defining-regions": {
            "put": {
                "tags": [
                    "region"
                ],
                "summary": "Set the regions that define a compound region.",
                "description": "Replaces the complete member list of a metro area or regional\nassociation (`defining_regions`): members no longer listed are\nretired, missing ones are saved, and the flat column is set to\nexactly the list. The region links of structures and companies are\nnot derived here; call `POST /region/{id}/recompute-objects` with\n`apply=true` afterwards. Senior editors, administrators and\nautomation tokens.",
                "operationId": "put_api_region_defining_regions_set",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "The compound region.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "region_ids"
                                ],
                                "properties": {
                                    "region_ids": {
                                        "description": "The complete list of member region ids. An empty list clears the field.",
                                        "type": "array",
                                        "items": {
                                            "type": "integer",
                                            "format": "int64"
                                        }
                                    },
                                    "source": {
                                        "description": "Source recorded on the new member rows.",
                                        "type": "string"
                                    },
                                    "reason": {
                                        "description": "Required if the new list removes a member. Explain why the removed member should be removed.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "A member id is unknown, retired, or the region itself."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/region/{id}/recompute-objects": {
            "post": {
                "tags": [
                    "region"
                ],
                "summary": "Recompute the objects of a compound region.",
                "description": "Re-derives `object_region` for a compound region (metro area,\nregional association) from the members it is defined by: structures\nand companies linked to a member become linked to the compound.\nWithout `apply=true` the response lists the candidates only. For a\nsingle structure or company use `POST /object/{id}/recompute-regions`.",
                "operationId": "post_api_region_recompute_objects",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Region id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "apply": {
                                        "description": "Write the missing links. Default false.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/region/{id}": {
            "get": {
                "tags": [
                    "region"
                ],
                "summary": "Get a region.",
                "description": "One place at any tier: continent, country, state, county, city,\nborough, district, neighborhood or zone. Returns its names in every\nstored language, the tier (`regiongroupid`), its parent chain, the\ncenter pinpoint, area and population, and the boundary if one is\nstored.\n\nTiers are not uniform worldwide: a \"district\" is one level in Frankfurt\nand two in Berlin or New York. Read `regiongroupid` rather than assuming\na fixed depth.",
                "operationId": "get_api_region_get",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/RegionId"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            },
            "put": {
                "tags": [
                    "region"
                ],
                "summary": "Update a region.",
                "description": "Send only the fields you are changing. Permission keys on the region's\n**existing** tier, so an editor who may edit a zone cannot re-type it\ninto a city.",
                "operationId": "put_api_region_update",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/RegionId"
                    }
                ],
                "requestBody": {
                    "description": "Same field set as the create call; all optional here.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "names": {
                                        "description": "Display name per language, keyed by ISO 639-1 code.",
                                        "type": "object"
                                    },
                                    "names_other": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "short_name": {
                                        "type": "string"
                                    },
                                    "regiontypeid": {
                                        "type": "integer"
                                    },
                                    "parent_id": {
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "lat": {
                                        "description": "Optional WGS84 pinpoint latitude; supply with lon.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "lon": {
                                        "description": "Optional WGS84 pinpoint longitude; supply with lat.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180
                                    },
                                    "population": {
                                        "type": "integer"
                                    },
                                    "area": {
                                        "type": "number",
                                        "format": "float"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "region"
                ],
                "summary": "Delete a region.",
                "description": "Soft delete. Refused while anything still lives inside it: `409\nhas_structures` if any structure sits in the region or one of its\nsub-regions, `409 has_companies` for connected companies, and `409\nhas_children` if it still has child regions. Empty\nthe region first, call `GET /region/{id}/connected-structures` to see\nwhether it is deletable before offering the action to a user.",
                "operationId": "delete_api_region_delete",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/RegionId"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/region/{id}/boundary": {
            "delete": {
                "tags": [
                    "region"
                ],
                "summary": "Delete the currently active boundary of a region.",
                "description": "Retires the exact versioned boundary data row; the row itself remains\navailable in the audit history. Allowed for administrators or the\naccount that authored that boundary version. `reason` is mandatory.",
                "operationId": "delete_api_region_boundary_delete",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/RegionId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "type": "string",
                                        "maxLength": 150
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "A reason of at most 150 characters is required."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/street/{id}/upload": {
            "get": {
                "tags": [
                    "region"
                ],
                "summary": "Street Object Tool Upload pane.",
                "operationId": "get_api_street_upload_pane",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/region/by-coordinates": {
            "get": {
                "tags": [
                    "region"
                ],
                "summary": "Resolve coordinates to a region.",
                "description": "Resolves a point against the active SKYDB Region index. Used when placing\na building to determine its city.\n\nIt first selects the smallest matching Region boundary. A City request\nwithout a boundary match uses the nearest indexed City pinpoint.",
                "operationId": "get_api_region_by_coordinates",
                "parameters": [
                    {
                        "name": "lat",
                        "in": "query",
                        "description": "Latitude.",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 50.1109
                        }
                    },
                    {
                        "name": "lon",
                        "in": "query",
                        "description": "Longitude.",
                        "required": true,
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 8.6821
                        }
                    },
                    {
                        "name": "regiontype",
                        "in": "query",
                        "description": "Restrict the answer to one region type, e.g. `city`.",
                        "schema": {
                            "type": "string",
                            "example": "city"
                        }
                    },
                    {
                        "name": "regiongroup",
                        "in": "query",
                        "description": "Restrict the answer to one tier by `regiongroupid` (6 = city, 7 = first-level district, 10 = zone).",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "422": {
                        "description": "Coordinates or Region scope are invalid."
                    },
                    "503": {
                        "description": "The active Region index is unavailable."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/region": {
            "post": {
                "tags": [
                    "region"
                ],
                "summary": "Create a region.",
                "description": "Adds a place. `regiongroupid` decides the tier and, with it, who may\ncreate it: administrators and senior editors can create any tier,\nordinary editors can create zones (`regiongroupid=10`) only.\n\n`parent_id` must point at the tier directly above. A district belongs\nto a city, while a city belongs to a state or county. The boundary is\nnot set here; it is imported separately.",
                "operationId": "post_api_region_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "names",
                                    "regiongroupid",
                                    "parent_id"
                                ],
                                "properties": {
                                    "names": {
                                        "description": "Display name per language, keyed by ISO 639-1 code.",
                                        "type": "object",
                                        "example": {
                                            "en": "Bornheim",
                                            "de": "Bornheim"
                                        }
                                    },
                                    "names_other": {
                                        "description": "Additional searchable aliases, former names, local spellings.",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "short_name": {
                                        "type": "string"
                                    },
                                    "regiongroupid": {
                                        "description": "Tier: 3 country, 4 state, 5 county, 6 city, 7 first-level district, 8 second-level district, 10 zone, 13 metro area.",
                                        "type": "integer",
                                        "example": 10
                                    },
                                    "regiontypeid": {
                                        "description": "Type within the tier, city / town / village, borough / district / neighborhood.",
                                        "type": "integer"
                                    },
                                    "parent_id": {
                                        "description": "Region id of the tier directly above.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "lat": {
                                        "description": "Optional WGS84 pinpoint latitude; supply with lon.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "lon": {
                                        "description": "Optional WGS84 pinpoint longitude; supply with lat.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180
                                    },
                                    "population": {
                                        "type": "integer"
                                    },
                                    "area": {
                                        "description": "Area in km\u00b2.",
                                        "type": "number",
                                        "format": "float"
                                    },
                                    "isocode2digits": {
                                        "description": "Countries only.",
                                        "type": "string"
                                    },
                                    "isocode3digits": {
                                        "description": "Countries only.",
                                        "type": "string"
                                    },
                                    "fipscode": {
                                        "description": "US regions only.",
                                        "type": "string"
                                    },
                                    "confirm_not_duplicate": {
                                        "description": "Create despite a similarly named sibling.",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/{entity}/{id}/connected-structures": {
            "get": {
                "tags": [
                    "region"
                ],
                "summary": "Check whether a region or street can be deleted.",
                "description": "Returns how many structures are still attached (`count`), how many\ncompanies are attached (`companies`, regions only), how many child\nregions remain (`children`, always 0 for a street), and the\n`deletable` verdict. Call this before offering a delete action so the\nuser learns why it is blocked instead of hitting a `409`.",
                "operationId": "get_api_entity_connected_structures",
                "parameters": [
                    {
                        "name": "entity",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "region|street",
                            "enum": [
                                "region",
                                "street"
                            ]
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/regions/ranking": {
            "get": {
                "tags": [
                    "region"
                ],
                "summary": "Rank regions.",
                "description": "The \"most skyscrapers\" league tables: cities or countries ordered by\nhow many tall buildings they hold. Counts are channel membership, not a\nheight threshold: \"tall buildings\" is the default metric, \"skyscrapers\"\nis the narrower set. The same aggregation backs the city and country\nranking pages, so the numbers agree across the site.",
                "operationId": "get_api_regions_ranking",
                "parameters": [
                    {
                        "name": "regiongroup",
                        "in": "query",
                        "description": "Which tier to rank, 6 for cities, 3 for countries.",
                        "schema": {
                            "type": "integer",
                            "example": 6
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "description": "Ranking metric, e.g. tall-building count, skyscraper count or tallest structure.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "channel_id",
                        "in": "query",
                        "description": "Count membership of this channel instead of the default tall-building set.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "description": "Restrict the counted structures to a lifecycle status.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "population_min",
                        "in": "query",
                        "description": "Drop regions below this population.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Rows to return, 1 to 100.",
                        "schema": {
                            "type": "integer",
                            "default": 20,
                            "maximum": 100,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/regions/search": {
            "get": {
                "tags": [
                    "region"
                ],
                "summary": "Search regions (typeahead).",
                "description": "Name lookup across every tier, tolerant of accents, umlauts and typos,\nand matching in any stored language, `Muenchen`, `M\u00fcnchen` and `Munich`\nall find the same city.\n\nAnonymous callers must supply at least 3 characters and receive at most\n10 hits. A signed-in caller may also search with an empty `q` when\n`near_city` is set, to preload the regions of one city.",
                "operationId": "get_api_regions_search",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Search text. Minimum 3 characters for anonymous callers.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Maximum hits. Capped at 10 for anonymous callers.",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    },
                    {
                        "name": "groups",
                        "in": "query",
                        "description": "Comma-separated `regiongroupid` filter, restrict to certain tiers, e.g. `6` for cities only.",
                        "schema": {
                            "type": "string",
                            "example": "6,7"
                        }
                    },
                    {
                        "name": "near_city",
                        "in": "query",
                        "description": "Prefer regions in or near this city id.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/overview": {
            "get": {
                "tags": [
                    "region"
                ],
                "summary": "Get an entity overview.",
                "description": "The assembled dashboard for one entity, header, totals, statistics,\nranked lists, facts and the URLs behind each \"view all\". It is what the\n`/overview/` pages render, delivered in a single call so a client does\nnot have to stitch a dozen requests together.\n\nPass exactly one scope: `region`, `channel`, `company`, `recognition`,\n`collection` or `street`.",
                "operationId": "get_api_overview",
                "parameters": [
                    {
                        "name": "region",
                        "in": "query",
                        "description": "Region id to build the overview for.",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "channel",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "company",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "recognition",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "collection",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "street",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "list_limit",
                        "in": "query",
                        "description": "Rows per embedded list.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/street/{id}": {
            "get": {
                "tags": [
                    "street"
                ],
                "summary": "Get a street.",
                "description": "A street is its own entity, not a region: it carries the city it runs\nthrough, its alternative names, postcode and the structures addressed\non it. Buildings link to streets through smart addresses.",
                "operationId": "get_api_street_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "SKYDB street id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            },
            "post": {
                "tags": [
                    "street"
                ],
                "summary": "Update a street.",
                "description": "Send only the fields you are changing. Permission is **tiered by how\nmany buildings the street carries**: a street with no buildings can be\nedited by any signed-in member, one with at least one building needs an\neditor, and a street with more than ten needs a senior editor. Renaming\na busy street rewrites many addresses at once, which is why the bar\nrises with its size.",
                "operationId": "post_api_street_save",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "SKYDB street id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "description": "Street name.",
                                        "type": "string"
                                    },
                                    "postcode": {
                                        "type": "string"
                                    },
                                    "address_sequence": {
                                        "description": "How house numbers run along the street. Drives neighbor resolution in smart addresses.",
                                        "type": "string"
                                    },
                                    "lat": {
                                        "description": "Optional WGS84 center latitude; supply with lon.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "lon": {
                                        "description": "Optional WGS84 center longitude; supply with lat.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180
                                    },
                                    "alt_names": {
                                        "description": "Alternative and historic names, also searchable.",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/street/{streetid}/neighbors": {
            "get": {
                "tags": [
                    "street"
                ],
                "summary": "List neighbouring streets.",
                "description": "The streets that cross or adjoin this one, used to walk an address grid.",
                "operationId": "get_api_street_neighbors",
                "parameters": [
                    {
                        "name": "streetid",
                        "in": "path",
                        "description": "SKYDB street id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/From"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/streets": {
            "get": {
                "tags": [
                    "street"
                ],
                "summary": "Search streets within a city (typeahead).",
                "description": "Name lookup scoped to one city, used by the address picker. The scope is\nthe city, so a street parented to a borough is still found when you pass\nthe city id.",
                "operationId": "get_api_streets_typeahead",
                "parameters": [
                    {
                        "name": "regionid",
                        "in": "query",
                        "description": "City id to search within.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Search text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "street"
                ],
                "summary": "Create a street.",
                "description": "Adds a street under a city. Use this when an address needs a street that\ndoes not exist yet; search first so you do not create a duplicate under\na spelling variant.",
                "operationId": "post_api_streets_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "required": [
                                    "name",
                                    "parent_id"
                                ],
                                "properties": {
                                    "name": {
                                        "description": "Street name.",
                                        "type": "string"
                                    },
                                    "parent_id": {
                                        "description": "City the street belongs to.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "lat": {
                                        "description": "Optional WGS84 center latitude; supply with lon.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "lon": {
                                        "description": "Optional WGS84 center longitude; supply with lat.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/city/{id}/streets": {
            "get": {
                "tags": [
                    "street"
                ],
                "summary": "List a city's streets.",
                "description": "The paged street directory for one city, including streets that hang off\nits boroughs. Each row carries the street's building count.",
                "operationId": "get_api_city_streets",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "City region id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Filter by name.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "p",
                        "in": "query",
                        "description": "Page number, one-based.",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "size",
                        "in": "query",
                        "description": "Rows per page.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "description": "Sort axis, name or building count.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "dir",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/timeline": {
            "get": {
                "tags": [
                    "content"
                ],
                "operationId": "get_api_timeline_list",
                "parameters": [
                    {
                        "name": "objectid",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "objecttypeid",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "timeline_categoryid",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "temporality",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "actual",
                                "expected"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/From"
                    },
                    {
                        "$ref": "#/components/parameters/PageSize"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "content"
                ],
                "operationId": "post_api_timeline_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "objectid",
                                    "timeline_categoryid",
                                    "date"
                                ],
                                "properties": {
                                    "objectid": {
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "timeline_categoryid": {
                                        "type": "string"
                                    },
                                    "date": {
                                        "type": "string",
                                        "example": "2026-08-27"
                                    },
                                    "temporality": {
                                        "type": "string",
                                        "enum": [
                                            "actual",
                                            "expected"
                                        ]
                                    },
                                    "sourceid": {
                                        "type": "integer",
                                        "format": "int64"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "422": {
                        "description": "Field validation failed."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/timeline/{id}": {
            "get": {
                "tags": [
                    "content"
                ],
                "operationId": "get_api_timeline_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "content"
                ],
                "operationId": "put_api_timeline_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "422": {
                        "description": "Field validation failed."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "content"
                ],
                "operationId": "delete_api_timeline_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "description": "Explain why this Timeline item should be removed.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "422": {
                        "$ref": "#/components/responses/UnprocessableEntity"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/weblinks": {
            "get": {
                "tags": [
                    "content"
                ],
                "operationId": "get_api_weblinks_list",
                "parameters": [
                    {
                        "name": "objectid",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "format": "int64"
                        }
                    },
                    {
                        "name": "objecttypeid",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "datatypeid",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "language",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/From"
                    },
                    {
                        "$ref": "#/components/parameters/PageSize"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            },
            "post": {
                "tags": [
                    "content"
                ],
                "operationId": "post_api_weblinks_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "objectid",
                                    "datatypeid",
                                    "url"
                                ],
                                "properties": {
                                    "objectid": {
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "datatypeid": {
                                        "type": "string"
                                    },
                                    "url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "language": {
                                        "type": "string"
                                    },
                                    "sourceid": {
                                        "type": "integer",
                                        "format": "int64"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "422": {
                        "description": "Field validation failed."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/weblinks/{id}": {
            "get": {
                "tags": [
                    "content"
                ],
                "operationId": "get_api_weblinks_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            },
            "put": {
                "tags": [
                    "content"
                ],
                "operationId": "put_api_weblinks_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "422": {
                        "description": "Field validation failed."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "content"
                ],
                "operationId": "delete_api_weblinks_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "description": "Explain why this Weblink should be removed.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "422": {
                        "$ref": "#/components/responses/UnprocessableEntity"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/rich-text/mention-backfill": {
            "get": {
                "tags": [
                    "internal"
                ],
                "summary": "Preview one bounded target batch without changing stored content.",
                "operationId": "get_api_rich_text_mention_backfill_preview",
                "parameters": [
                    {
                        "name": "target",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "after_id",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 0
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "maximum": 250,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "internal"
                ],
                "summary": "Persist one bounded batch and report any deferred managed projection rebuilds.",
                "operationId": "post_api_rich_text_mention_backfill_apply",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "target"
                                ],
                                "properties": {
                                    "target": {
                                        "type": "string"
                                    },
                                    "after_id": {
                                        "type": "integer",
                                        "minimum": 0
                                    },
                                    "limit": {
                                        "type": "integer",
                                        "maximum": 250,
                                        "minimum": 1
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/sameas": {
            "get": {
                "tags": [
                    "internal"
                ],
                "operationId": "get_api_sameas_list",
                "parameters": [
                    {
                        "name": "object_id",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "relation_state",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "candidate",
                                "accepted",
                                "ambiguous",
                                "quarantined",
                                "rejected",
                                "disconnected"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "pagesize",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "maximum": 100,
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "internal"
                ],
                "operationId": "post_api_sameas_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "left_object_id",
                                    "right_object_id",
                                    "confidence",
                                    "match_method"
                                ],
                                "properties": {
                                    "left_object_id": {
                                        "type": "integer",
                                        "format": "int64",
                                        "minimum": 1
                                    },
                                    "right_object_id": {
                                        "type": "integer",
                                        "format": "int64",
                                        "minimum": 1
                                    },
                                    "relation_state": {
                                        "type": "string",
                                        "default": "candidate",
                                        "enum": [
                                            "candidate",
                                            "accepted",
                                            "ambiguous",
                                            "quarantined",
                                            "rejected",
                                            "disconnected"
                                        ]
                                    },
                                    "confidence": {
                                        "type": "number",
                                        "format": "float",
                                        "maximum": 1,
                                        "minimum": 0
                                    },
                                    "match_method": {
                                        "type": "string"
                                    },
                                    "resolver_version": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "source": {
                                        "nullable": true,
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "string"
                                            }
                                        ]
                                    },
                                    "time_start": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "time_anchor": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "time_end": {
                                        "type": "integer",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/sameas/{id}": {
            "get": {
                "tags": [
                    "internal"
                ],
                "operationId": "get_api_sameas_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "internal"
                ],
                "operationId": "delete_api_sameas_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "description": "Explain why this SameAs Connection should be removed.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/UnprocessableEntity"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "internal"
                ],
                "operationId": "patch_api_sameas_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "relation_state": {
                                        "type": "string",
                                        "enum": [
                                            "candidate",
                                            "accepted",
                                            "ambiguous",
                                            "quarantined",
                                            "rejected",
                                            "disconnected"
                                        ]
                                    },
                                    "confidence": {
                                        "type": "number",
                                        "format": "float",
                                        "maximum": 1,
                                        "minimum": 0
                                    },
                                    "match_method": {
                                        "type": "string"
                                    },
                                    "resolver_version": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "source": {
                                        "nullable": true,
                                        "oneOf": [
                                            {
                                                "type": "integer"
                                            },
                                            {
                                                "type": "string"
                                            }
                                        ]
                                    },
                                    "time_start": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "time_anchor": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "time_end": {
                                        "type": "integer",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/slidedeck/available": {
            "post": {
                "tags": [
                    "misc"
                ],
                "summary": "Reports which of the given objects own a file the slideshow would show.",
                "description": "A \"Run slideshow\" entry that opens nothing is worse than no entry, so a\ncontext menu asks this on open and reveals the entry only for the ids\nthat come back. One aggregation answers a whole page of ids, so a list\ncosts one request no matter how many rows it has.",
                "operationId": "post_api_slidedeck_available",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "object_ids"
                                ],
                                "properties": {
                                    "object_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer",
                                            "format": "int64"
                                        }
                                    },
                                    "exclude_filecategory": {
                                        "type": "string",
                                        "example": "266,273"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/slidedeck/open": {
            "post": {
                "tags": [
                    "misc"
                ],
                "operationId": "post_api_slidedeck_open",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "params"
                                ],
                                "properties": {
                                    "params": {
                                        "type": "object"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/streetaddress/{id}": {
            "delete": {
                "tags": [
                    "internal"
                ],
                "operationId": "delete_api_streetaddress_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "description": "Explain why this Street Address connection should be removed.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/UnprocessableEntity"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}": {
            "get": {
                "tags": [
                    "structure"
                ],
                "summary": "Get a structure.",
                "description": "The public record for one structure. These are the facts the building page shows\na signed-out visitor: name and address, pinpoint, height and floor\ncount, lifecycle years and status, structural form, main usage, city and\ncountry, the key image, and `page_url` / `api_url` to get back here.\nEvery URL in the response carries its host.\n\nLifecycle dates are partial-date integers, not timestamps: `20260814`\n(full date), `20260800` (month known), `20260000` (year only). Compare\nthem as integers. A plain `< 2026` matches nothing.\n\nPhotos and the region path are opt-in: `?include=photos`,\n`?include=region_path`, so a caller asking for a height does not pay\nfor a 48-object gallery. The key image rides along either way.\n\nAccounts with an editor, senior, administrator, Insights, Premium or\nAPI-access flag additionally receive `companies`, `channels`, `rating`,\n`recognitions`, `height_rankings`, `height_extra_rows`, `weblinks`,\n`timeline`, `smart_addresses`, `region_path`, `structural_kind`, `slug`\nand `photo_count`.",
                "operationId": "get_api_structure_get",
                "parameters": [
                    {
                        "name": "include",
                        "in": "query",
                        "description": "Comma-separated list of optional blocks to include. Defaults to every block except `photos`, `region_path` and `height_rankings`.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "photos,region_path"
                        }
                    },
                    {
                        "name": "with_rankings",
                        "in": "query",
                        "description": "Include the height rankings (worldwide / country / city) this structure holds. Costs an extra aggregation.",
                        "required": false,
                        "schema": {
                            "type": "boolean",
                            "default": false
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    },
                    {}
                ]
            }
        },
        "/api/v1/structure/{id}/boundary": {
            "delete": {
                "tags": [
                    "structure"
                ],
                "summary": "Delete the currently active boundary of a structure.",
                "description": "Retires the exact versioned boundary data row while preserving it in the\naudit history. Administrators and the author of that boundary version may\ndelete it. A reason is required.",
                "operationId": "delete_api_structure_boundary_delete",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "type": "string",
                                        "maxLength": 150
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "A reason of at most 150 characters is required."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/smart-addresses": {
            "get": {
                "tags": [
                    "structure"
                ],
                "summary": "List a structure's smart addresses.",
                "description": "Every street the structure sits on, with the previous and next\nneighbouring house number pre-resolved. A structure can carry several\naddresses (corner buildings, complexes) and an address can be a house\nnumber range. Lighter than the full record when you only need addresses.\n\nRequires a paid plan or editorial role, like the `smart_addresses`\nblock inside the record: the anonymous building page shows one plain\naddress, not the resolved neighbor ranges.",
                "operationId": "get_api_structure_smart_addresses",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/construction-calendar": {
            "get": {
                "tags": [
                    "structure"
                ],
                "summary": "Get the construction calendar.",
                "description": "Public construction-phase photos grouped by year and month. This reads\nthe file index directly; page views never fall back to PostgreSQL.",
                "operationId": "get_api_structure_construction_calendar",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/files": {
            "get": {
                "tags": [
                    "structure"
                ],
                "summary": "List a structure's files.",
                "description": "Photos and other media attached to the structure, each with its\ncopyright holder, license and the URLs of the generated sizes. Private\nfiles are never returned on this endpoint, regardless of who is asking.",
                "operationId": "get_api_structure_files",
                "parameters": [
                    {
                        "name": "category",
                        "in": "query",
                        "description": "Optional File category id.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "takenyear",
                        "in": "query",
                        "description": "Optional capture year.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "takenmonth",
                        "in": "query",
                        "description": "Optional capture month. Applied with `takenyear`.",
                        "schema": {
                            "type": "integer",
                            "maximum": 12,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Maximum returned files.",
                        "schema": {
                            "type": "integer",
                            "default": 6,
                            "maximum": 24,
                            "minimum": 1
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/structures": {
            "get": {
                "tags": [
                    "structure"
                ],
                "summary": "Search and list structures.",
                "description": "The main query surface: every filter the site's own search page uses,\ncombinable in one call. With no parameters it returns the newest\nstructures.\n\n**Scopes** narrow the result to everything inside a place, channel,\ncollection, street, company portfolio or contributor. Pass either the\nshort alias (`region=505452022`) or the explicit form\n(`region_id=505452022`). They are equivalent.\n\n**Radius search** needs `near_lat` and `near_lon`; `near_distance`\naccepts a bare number (meters) or a unit suffix (`500m`, `2km`). It is\ncapped at 1000 m. Unit conversion happens before the cap, so `2km`\nclamps rather than bypasses it.\n\n**Paging:** page one is public, deeper pages need a session. Iterate\nwith `from=0,100,200,\u2026`.",
                "operationId": "get_api_structures_list",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/From"
                    },
                    {
                        "$ref": "#/components/parameters/PageSize"
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Hard cap on total rows returned, also maximum 100.",
                        "schema": {
                            "type": "integer",
                            "maximum": 100
                        }
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "description": "Sort axis, e.g. `height`, `floors`, `year`, `name`, `updated`.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "sortdirection",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "desc",
                            "enum": [
                                "asc",
                                "desc"
                            ]
                        }
                    },
                    {
                        "name": "keyword",
                        "in": "query",
                        "description": "Full-text search over names and addresses. Typo-tolerant and multilingual; a house number plus street name resolves to the building on that address.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "region",
                        "in": "query",
                        "description": "Restrict to structures inside this region, at any depth (a country id also returns its cities' buildings). Alias of `region_id`.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "street",
                        "in": "query",
                        "description": "Restrict to structures on this street. Alias of `street_id`.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "company",
                        "in": "query",
                        "description": "Restrict to this company's portfolio, every structure it is linked to in any role. Alias of `company_id`.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "channel",
                        "in": "query",
                        "description": "Restrict to a channel, e.g. the tall-building channels. Alias of `channel_id`; `channel_ids` takes a CSV.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "collection",
                        "in": "query",
                        "description": "Restrict to a curated collection. Alias of `collection_id`.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "recognition",
                        "in": "query",
                        "description": "Restrict to holders of an award or recognition. Alias of `recognition_id`.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "account",
                        "in": "query",
                        "description": "Restrict to structures created by this contributor. Alias of `account_id`.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "description": "Lifecycle status code, e.g. `status.4.1` (completed), `status.3.2` (under construction, frame assembly), `status.1.3` (never completed).",
                        "schema": {
                            "type": "string",
                            "example": "status.4.1"
                        }
                    },
                    {
                        "name": "structuralform",
                        "in": "query",
                        "description": "Structural form code, e.g. `02.1` (high-rise building).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "usage",
                        "in": "query",
                        "description": "Usage code. `usage_main` and `usage_side` narrow it to primary or secondary use.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "style",
                        "in": "query",
                        "description": "Architectural style code.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "feature",
                        "in": "query",
                        "description": "Feature code (observation deck, helipad, \u2026).",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "height_from",
                        "in": "query",
                        "description": "Minimum height in meters. Pair with `height_to` for a band.",
                        "schema": {
                            "type": "number",
                            "format": "float"
                        }
                    },
                    {
                        "name": "height_to",
                        "in": "query",
                        "description": "Maximum height in meters.",
                        "schema": {
                            "type": "number",
                            "format": "float"
                        }
                    },
                    {
                        "name": "height_measure",
                        "in": "query",
                        "description": "Which height measure `height_from`/`height_to` and `sort=height` apply to. Defaults to the building mass height (the height of record). Structures without the chosen measure are excluded by the range and sort last.",
                        "schema": {
                            "type": "string",
                            "default": "height_buildingmass",
                            "enum": [
                                "height_buildingmass",
                                "height_tip",
                                "height_architectural",
                                "height_mainroof",
                                "height_enclosure",
                                "height_topfloor",
                                "height_observationfloor"
                            ]
                        }
                    },
                    {
                        "name": "creation_from",
                        "in": "query",
                        "description": "Earliest date the structure was added to SKYDB (`setupdate`), as YYYY-MM-DD. Inclusive.",
                        "schema": {
                            "type": "string",
                            "format": "date",
                            "example": "2026-01-01"
                        }
                    },
                    {
                        "name": "creation_to",
                        "in": "query",
                        "description": "Latest date the structure was added to SKYDB (`setupdate`), as YYYY-MM-DD. Inclusive of the whole day.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "update_from",
                        "in": "query",
                        "description": "Earliest date the structure was last edited (`updatedate`), as YYYY-MM-DD. Inclusive.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "update_to",
                        "in": "query",
                        "description": "Latest date the structure was last edited (`updatedate`), as YYYY-MM-DD. Inclusive of the whole day.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "floors_from",
                        "in": "query",
                        "description": "Minimum above-ground floor count.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "floors_to",
                        "in": "query",
                        "description": "Maximum above-ground floor count.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "year_from",
                        "in": "query",
                        "description": "Earliest completion year (four digits).",
                        "schema": {
                            "type": "integer",
                            "example": 2000
                        }
                    },
                    {
                        "name": "year_to",
                        "in": "query",
                        "description": "Latest completion year (four digits).",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "near_lat",
                        "in": "query",
                        "description": "Radius-search origin latitude. Requires `near_lon`.",
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 50.1109
                        }
                    },
                    {
                        "name": "near_lon",
                        "in": "query",
                        "description": "Radius-search origin longitude. Requires `near_lat`.",
                        "schema": {
                            "type": "number",
                            "format": "double",
                            "example": 8.6821
                        }
                    },
                    {
                        "name": "near_distance",
                        "in": "query",
                        "description": "Radius around the origin. Bare numbers are meters; `500m` and `2km` also work. Capped at 1000 m, default 2000 m for internal callers.",
                        "schema": {
                            "type": "string",
                            "example": "500m"
                        }
                    },
                    {
                        "name": "exclude_ids",
                        "in": "query",
                        "description": "Comma-separated structure ids to drop from the result. Useful to exclude the structure you are showing neighbors for.",
                        "schema": {
                            "type": "string",
                            "example": "505452022,123456789"
                        }
                    },
                    {
                        "name": "displaymode",
                        "in": "query",
                        "description": "Row shape: `list`, `gallery` or `details`.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "list",
                                "gallery",
                                "details"
                            ]
                        }
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "description": "Field set per row. `full` returns the complete record instead of the list projection.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/structure/statistics": {
            "get": {
                "tags": [
                    "structure"
                ],
                "summary": "Aggregate statistics over a filtered set.",
                "description": "Returns counts and distributions (by status, decade, height band, usage,\nmaterial, \u2026) for the set of structures matching the filters, without\nreturning the structures themselves. Accepts the same scope and\nattribute filters as `GET /structures`.\n\nIt additionally accepts **data-quality filters** that select records with\nsomething missing or inconsistent, `nocoords`, `noyear`, `no_images`,\n`no_heights`, `no_floors`, `no_usage`, `no_companies`, `no_weblinks`,\n`no_ratings`, and `completion_outdated` (a structure still marked planned\nor under construction whose completion year is already in the past).\nThese drive the editorial to-do lists.",
                "operationId": "get_api_structure_statistics",
                "parameters": [
                    {
                        "name": "region",
                        "in": "query",
                        "description": "Scope to a region, at any depth.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "channel",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "company",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "street",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "account",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "keyword",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "usage",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "style",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "structuralform",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "height_from",
                        "in": "query",
                        "schema": {
                            "type": "number"
                        }
                    },
                    {
                        "name": "height_to",
                        "in": "query",
                        "schema": {
                            "type": "number"
                        }
                    },
                    {
                        "name": "floors_from",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "floors_to",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "year_from",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "year_to",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "year_field",
                        "in": "query",
                        "description": "Which lifecycle date `year_from` / `year_to` apply to. Defaults to completion.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "completion_outdated",
                        "in": "query",
                        "description": "Only structures still marked planned or under construction whose completion year has already passed.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "nocoords",
                        "in": "query",
                        "description": "Only structures without a pinpoint.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "noyear",
                        "in": "query",
                        "description": "Only structures without any lifecycle year.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "no_images",
                        "in": "query",
                        "description": "Only structures with no photo attached.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "no_heights",
                        "in": "query",
                        "description": "Only structures with no height recorded.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "no_floors",
                        "in": "query",
                        "description": "Only structures with no floor count.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "no_usage",
                        "in": "query",
                        "description": "Only structures with no usage recorded.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "no_companies",
                        "in": "query",
                        "description": "Only structures with no company linked.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "no_weblinks",
                        "in": "query",
                        "description": "Only structures with no external link.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "no_ratings",
                        "in": "query",
                        "description": "Only structures nobody has rated.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "description": "Only structures edited on or after this date (`YYYY-MM-DD`).",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "not_updated_since",
                        "in": "query",
                        "description": "Only structures untouched since this date (`YYYY-MM-DD`).",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/hierarchy-tree": {
            "get": {
                "tags": [
                    "structure"
                ],
                "summary": "Get the full hierarchy tree.",
                "description": "The whole parent/child tree the structure belongs to, from the topmost\nancestor down through every sibling and descendant, not just its direct\nneighbors.",
                "operationId": "get_api_structure_hierarchy_tree",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/companies": {
            "get": {
                "tags": [
                    "structure"
                ],
                "summary": "List the companies attached to the structure.",
                "description": "Architects, developers, contractors, engineers and other roles, each\nwith the role it was involved in and the period it held it. Retired\nlinks are kept alongside current ones rather than deleted.\n\nRequires a paid plan or editorial role, company data is a licensed\npart of the dataset.",
                "operationId": "get_api_structure_companies",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "structure"
                ],
                "summary": "Save the companies attached to the structure.",
                "description": "Existing links use `companies[connection_id]=company_id`; posting an\nempty company id retires that link. New links use\n`companies_new[company_role_id][]=company_id`.\n\nRequires a paid plan or editorial role.",
                "operationId": "post_api_structure_save_companies",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "properties": {
                                    "companies": {
                                        "description": "Existing connection ids mapped to their current Company id; an empty value retires the connection.",
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string"
                                        }
                                    },
                                    "companies_new": {
                                        "description": "CompanyRole category ids mapped to one or more Company ids.",
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "array",
                                            "items": {
                                                "type": "integer",
                                                "format": "int64"
                                            }
                                        }
                                    },
                                    "default_source_type": {
                                        "type": "string"
                                    },
                                    "default_source_date": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "default_source_details": {
                                        "type": "string"
                                    },
                                    "source_type": {
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string"
                                        }
                                    },
                                    "source_date": {
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string",
                                            "format": "date"
                                        }
                                    },
                                    "source_details": {
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "One or more CompanyRole values are invalid."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/timeline": {
            "get": {
                "tags": [
                    "structure"
                ],
                "summary": "List the structure's timeline.",
                "description": "Dated facts in the structure's life that are not lifecycle milestones:\nfires, ownership changes, renamings, incidents. Maintained explicitly;\nediting a lifecycle column does not fabricate a Timeline item here.\n\nRequires a paid plan or editorial role.",
                "operationId": "get_api_structure_timeline",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "structure"
                ],
                "summary": "Save the structure's timeline.",
                "description": "Writes the dated non-lifecycle facts (fires, ownership changes,\nrenamings). Send them in a `timeline` array. Sources follow the same\nbatch-default plus per-row override pattern as the weblinks endpoint.\n\nRequires a paid plan or editorial role.",
                "operationId": "post_api_structure_save_timeline",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "properties": {
                                    "timeline": {
                                        "type": "array",
                                        "items": {
                                            "type": "object"
                                        }
                                    },
                                    "default_source_type": {
                                        "type": "string"
                                    },
                                    "default_source_date": {
                                        "type": "string",
                                        "format": "date"
                                    },
                                    "default_source_details": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "One or more Timeline values are invalid."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/data": {
            "post": {
                "tags": [
                    "structure"
                ],
                "summary": "Create or update a structure's data.",
                "description": "The single write path for structure content. The body is keyed by data\nfield name (`name`, `height_architectural`, `floors_og`,\n`construction_end`, `status`, `structural_form`, \u2026); send only the\nfields you are changing. Each write is recorded with its author, the\ntime, and its source. A superseded value is retired, never overwritten\nin place, so the audit trail survives.\n\n**Creating:** post to `id=0`. `name`, `lat` and `lon` are required. The\nserver first checks for an existing structure with a similar name within\n500 m and answers `409` with the candidates if it finds any; resubmit\nwith `confirm_not_duplicate=true` to create anyway. The new id comes\nback as `new_id`.\n\nA different lifecycle status makes a structure a different structure: a\nnew tower on the plot of a demolished one is a new record, not an edit\nof the old one.",
                "operationId": "post_api_structure_save_data",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Structure id to update, or `0` to create a new one.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "description": "Data fields to write, keyed by field name.",
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "description": "Structure name. Required when creating.",
                                        "type": "string"
                                    },
                                    "name_language": {
                                        "description": "Language slot used for name-family fields. Must be a known SKYDB ISO language code.",
                                        "type": "string",
                                        "pattern": "^[a-z]{2,3}$",
                                        "example": "ar"
                                    },
                                    "lat": {
                                        "description": "WGS84 pinpoint latitude. Required when creating.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 90,
                                        "minimum": -90
                                    },
                                    "lon": {
                                        "description": "WGS84 pinpoint longitude. Required when creating.",
                                        "type": "number",
                                        "format": "double",
                                        "maximum": 180,
                                        "minimum": -180
                                    },
                                    "confirm_not_duplicate": {
                                        "description": "Resubmit with `true` to create despite nearby duplicate candidates.",
                                        "type": "boolean"
                                    },
                                    "regionid": {
                                        "description": "City the structure belongs to. Derived from the pinpoint when omitted.",
                                        "type": "integer"
                                    },
                                    "address": {
                                        "description": "Source address text in address_language (or the signed-in account language when omitted).",
                                        "type": "string"
                                    },
                                    "address_language": {
                                        "description": "Language slot to write for address. Must be a known SKYDB ISO language code.",
                                        "type": "string",
                                        "pattern": "^[a-z]{2,3}$",
                                        "example": "ko"
                                    },
                                    "status": {
                                        "description": "Lifecycle status category. Without status and structural_form the structure stays inactive and outside the duplicate check.",
                                        "type": "string",
                                        "example": "status.4.1"
                                    },
                                    "structural_form": {
                                        "description": "Structural form category.",
                                        "type": "string",
                                        "example": "structural_form.02.1.2.1"
                                    },
                                    "default_source_id": {
                                        "description": "Existing Data Source used by changed fields without an override.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "default_source_type": {
                                        "description": "Source-type category used when creating a new Data Source.",
                                        "type": "string"
                                    },
                                    "default_source_date": {
                                        "description": "Date of that source, ISO 8601.",
                                        "type": "string"
                                    },
                                    "default_source_details": {
                                        "description": "Free text: URL, document, page.",
                                        "type": "string"
                                    },
                                    "default_source_valid_from": {
                                        "description": "Default Valid from as YYYY, YYYY-MM, or YYYY-MM-DD.",
                                        "type": "string"
                                    },
                                    "default_source_valid_to": {
                                        "description": "Default Valid to as YYYY, YYYY-MM, or YYYY-MM-DD.",
                                        "type": "string"
                                    },
                                    "source_id": {
                                        "description": "Per-field existing Data Source IDs, keyed by field name.",
                                        "type": "object"
                                    },
                                    "source_type": {
                                        "description": "Per-field source, keyed by field name; overrides default_source_type.",
                                        "type": "object"
                                    },
                                    "source_date": {
                                        "description": "Per-field source date, keyed by field name.",
                                        "type": "object"
                                    },
                                    "source_details": {
                                        "description": "Per-field source details, keyed by field name. A new explanation is required when removing a stored value or Smart Address connection, including one item from a multivalue field.",
                                        "type": "object"
                                    },
                                    "source_valid_from": {
                                        "description": "Per-field Valid from values, keyed by field name.",
                                        "type": "object"
                                    },
                                    "source_valid_to": {
                                        "description": "Per-field Valid to values, keyed by field name.",
                                        "type": "object"
                                    },
                                    "historical_assertions": {
                                        "description": "Optional per-DataID validity edits. They are validated and versioned atomically with the other fields.",
                                        "type": "array",
                                        "items": {
                                            "$ref": "#/components/schemas/ObjectToolAssertionDraft"
                                        }
                                    }
                                },
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The saved fields, Structure snapshot, and resulting immutable Object version.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ObjectToolWriteEnvelope"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/parent": {
            "post": {
                "tags": [
                    "structure"
                ],
                "summary": "Attach the structure to a parent, or detach it.",
                "description": "Connects this structure as a child of another: a building into a\ncomplex, a complex into a cluster. Send `disconnect=true` to remove the\nexisting link instead.",
                "operationId": "post_api_structure_set_parent",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "parent_id"
                                ],
                                "properties": {
                                    "parent_id": {
                                        "description": "Structure id of the direct parent.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "disconnect": {
                                        "description": "Retire this exact direct parent connection.",
                                        "type": "boolean"
                                    },
                                    "reason": {
                                        "description": "Required when disconnect is true. Explain why the direct connection should be removed.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "The parent id is invalid, creates a cycle, violates the hierarchy kind rules, or a disconnect has no removal reason."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/rate": {
            "post": {
                "tags": [
                    "structure"
                ],
                "summary": "Rate the structure.",
                "description": "Records the signed-in member's rating. One rating per member, posting\nagain replaces the previous one.",
                "operationId": "post_api_structure_rate",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "stars"
                                ],
                                "properties": {
                                    "stars": {
                                        "description": "Half-star increments from 0.5 to 5.",
                                        "type": "number",
                                        "format": "float",
                                        "maximum": 5,
                                        "minimum": 0.5
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "The rating is outside the supported half-star range."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structure/{id}/delete": {
            "post": {
                "tags": [
                    "structure"
                ],
                "summary": "Delete the structure.",
                "description": "A soft delete: the record stops being served but is not erased. Give a\n`reason`, deletions are auditable like any other edit.\n\nA structure carrying photos, company links, weblinks or Timeline items cannot\nsimply vanish, so the request is rejected unless you say what happens\nto them via `attachments`: `keep` leaves them on the deleted record,\n`reassign` moves selected groups to the structure named in\n`reassign_to` (use this when merging duplicates), and `delete` retires\nthem too. Only senior editors and administrators may choose how\nattachments are handled; other owners receive `409` while content is\nattached.",
                "operationId": "post_api_structure_delete",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/StructureId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "description": "Why the structure is being deleted.",
                                        "type": "string"
                                    },
                                    "comment": {
                                        "description": "Optional free-text detail.",
                                        "type": "string"
                                    },
                                    "attachments": {
                                        "description": "Senior/admin only. What to do with attached content.",
                                        "type": "string",
                                        "enum": [
                                            "keep",
                                            "reassign",
                                            "delete"
                                        ]
                                    },
                                    "reassign_to": {
                                        "description": "Target structure id. Required when `attachments=reassign`.",
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "move": {
                                        "description": "Attachment groups moved during reassignment. Omit to move all groups.",
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "enum": [
                                                "photos",
                                                "companies",
                                                "weblinks",
                                                "timeline"
                                            ]
                                        }
                                    },
                                    "object_data": {
                                        "description": "How canonical Data rows are handled during reassignment.",
                                        "type": "string",
                                        "enum": [
                                            "disregard",
                                            "merge_missing",
                                            "merge_higher_rank"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    },
                    "422": {
                        "description": "A required field or reassignment option is invalid."
                    },
                    "500": {
                        "description": "The atomic deletion transaction failed; no deletion was committed."
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        },
        "/api/v1/structureparent/{id}": {
            "delete": {
                "tags": [
                    "internal"
                ],
                "operationId": "delete_api_structureparent_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "reason"
                                ],
                                "properties": {
                                    "reason": {
                                        "description": "Explain why this direct parent connection should be removed.",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Success"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/UnprocessableEntity"
                    }
                },
                "security": [
                    {
                        "bearerToken": []
                    },
                    {
                        "sessionCookie": [],
                        "csrfToken": []
                    }
                ]
            }
        }
    },
    "components": {
        "schemas": {
            "Meta": {
                "properties": {
                    "timestamp": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "request_id": {
                        "description": "Quote this when reporting a problem.",
                        "type": "string"
                    },
                    "api_version": {
                        "type": "string",
                        "example": "v1"
                    },
                    "pagination": {
                        "$ref": "#/components/schemas/Pagination"
                    }
                },
                "type": "object"
            },
            "Pagination": {
                "description": "Present on list responses only.",
                "properties": {
                    "page": {
                        "type": "integer",
                        "example": 1
                    },
                    "page_size": {
                        "type": "integer",
                        "example": 100
                    },
                    "total_count": {
                        "type": "integer",
                        "example": 4312
                    },
                    "total_pages": {
                        "type": "integer",
                        "example": 44
                    },
                    "has_more": {
                        "type": "boolean",
                        "example": true
                    }
                },
                "type": "object"
            },
            "Envelope": {
                "description": "Success envelope. No `code` and no `errors`. Their absence is the success signal.",
                "properties": {
                    "ok": {
                        "type": "boolean",
                        "example": true
                    },
                    "data": {
                        "description": "The payload. Shape depends on the endpoint."
                    },
                    "message": {
                        "description": "Optional confirmation text on writes.",
                        "type": "string"
                    },
                    "meta": {
                        "$ref": "#/components/schemas/Meta"
                    }
                },
                "type": "object"
            },
            "ErrorEnvelope": {
                "description": "Error envelope. Branch on `code`; `message` is localized prose for humans.",
                "properties": {
                    "ok": {
                        "type": "boolean",
                        "example": false
                    },
                    "code": {
                        "type": "string",
                        "example": "not_found"
                    },
                    "message": {
                        "type": "string",
                        "example": "Structure not found."
                    },
                    "errors": {
                        "description": "Per-field detail on validation failures.",
                        "type": "array",
                        "items": {
                            "properties": {
                                "field": {
                                    "type": "string"
                                },
                                "code": {
                                    "type": "string"
                                },
                                "message": {
                                    "type": "string"
                                }
                            },
                            "type": "object"
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/Meta"
                    }
                },
                "type": "object"
            },
            "DataSourceInput": {
                "description": "Select an existing Data Source by `sourceid`, or resolve a new one from `type` plus `details`. `date` is stored as Date witnessed on the Data assertion.",
                "properties": {
                    "sourceid": {
                        "description": "Existing Data Source ID.",
                        "type": "integer",
                        "format": "int64"
                    },
                    "type": {
                        "description": "Source-type category id, such as source.3.5.",
                        "type": "string"
                    },
                    "date": {
                        "description": "Date witnessed as YYYY, YYYY-MM, or YYYY-MM-DD.",
                        "type": "string"
                    },
                    "details": {
                        "description": "Citation text, URL, title, page, or observation details.",
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "ObjectToolAssertionDraft": {
                "description": "One per-DataID validity edit submitted in the same transaction as the Object Tool fields. Existing assertions use dataid. Set selected=false for an accepted historical value; a historical value requires time_start or time_end. Set remove=true with a historical dataid and removal_reason to remove it from the new Object version.",
                "required": [
                    "datatypeid"
                ],
                "properties": {
                    "datatypeid": {
                        "type": "string",
                        "example": "floors_og"
                    },
                    "source_key": {
                        "description": "Object Tool field key used for its per-field source override. Defaults to datatypeid.",
                        "type": "string",
                        "nullable": true
                    },
                    "dataid": {
                        "type": "integer",
                        "format": "int64",
                        "nullable": true
                    },
                    "value": {
                        "example": "63",
                        "nullable": true
                    },
                    "language": {
                        "type": "string",
                        "nullable": true
                    },
                    "sourceid": {
                        "type": "integer",
                        "format": "int64",
                        "nullable": true
                    },
                    "time_start": {
                        "description": "Valid from as YYYY, YYYY-MM, or YYYY-MM-DD.",
                        "type": "string",
                        "example": "1968",
                        "nullable": true
                    },
                    "time_end": {
                        "description": "Valid to as YYYY, YYYY-MM, or YYYY-MM-DD.",
                        "type": "string",
                        "example": "2020-05",
                        "nullable": true
                    },
                    "selected": {
                        "type": "boolean",
                        "default": false
                    },
                    "remove": {
                        "type": "boolean",
                        "default": false
                    },
                    "removal_reason": {
                        "description": "Required with remove=true. Explain why this stored historical value should be removed.",
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "ObjectToolWriteResult": {
                "required": [
                    "id",
                    "saved",
                    "errors",
                    "objectversionid",
                    "version_number"
                ],
                "properties": {
                    "entity": {
                        "description": "Entity type for non-Structure Object Tool writes.",
                        "type": "string",
                        "nullable": true
                    },
                    "id": {
                        "description": "Saved Object id.",
                        "type": "integer",
                        "format": "int64"
                    },
                    "new_id": {
                        "description": "Created Object id, or null for an update.",
                        "type": "integer",
                        "format": "int64",
                        "nullable": true
                    },
                    "created": {
                        "type": "boolean"
                    },
                    "url": {
                        "type": "string",
                        "nullable": true
                    },
                    "saved": {
                        "description": "Field and assertion mutations committed in this Object version.",
                        "type": "array",
                        "items": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "errors": {
                        "type": "array",
                        "items": {
                            "properties": {
                                "field": {
                                    "type": "string"
                                },
                                "key": {
                                    "type": "string"
                                },
                                "code": {
                                    "description": "Stable machine-readable validation code.",
                                    "type": "string"
                                },
                                "message": {
                                    "type": "string"
                                }
                            },
                            "type": "object"
                        }
                    },
                    "objectversionid": {
                        "description": "Resulting immutable Object version id.",
                        "type": "integer",
                        "format": "int64",
                        "nullable": true
                    },
                    "version_number": {
                        "description": "Resulting version number within the Object.",
                        "type": "integer",
                        "nullable": true
                    }
                },
                "type": "object",
                "additionalProperties": true
            },
            "ObjectToolWriteEnvelope": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Envelope"
                    },
                    {
                        "properties": {
                            "data": {
                                "$ref": "#/components/schemas/ObjectToolWriteResult"
                            }
                        },
                        "type": "object"
                    }
                ]
            },
            "DataAssertion": {
                "description": "One immutable recorded value after server-side normalization.",
                "required": [
                    "dataid",
                    "datatypeid",
                    "selected"
                ],
                "properties": {
                    "key": {
                        "description": "Caller key echoed from the request when supplied.",
                        "type": "string"
                    },
                    "dataid": {
                        "description": "Stable Data assertion id.",
                        "type": "integer",
                        "format": "int64"
                    },
                    "objectversionid": {
                        "description": "Object version that first introduced this assertion.",
                        "type": "integer",
                        "format": "int64",
                        "nullable": true
                    },
                    "datatypeid": {
                        "description": "Field id.",
                        "type": "string"
                    },
                    "value": {
                        "description": "Stored value. Null marks a retirement assertion.",
                        "nullable": true
                    },
                    "language": {
                        "description": "Language code, or null for the Default slot.",
                        "type": "string",
                        "nullable": true
                    },
                    "sourceid": {
                        "description": "Resolved data source id.",
                        "type": "integer",
                        "format": "int64",
                        "nullable": true
                    },
                    "time_start": {
                        "description": "Valid from, as YYYY, YYYY-MM, or YYYY-MM-DD.",
                        "type": "string",
                        "nullable": true
                    },
                    "time_anchor": {
                        "description": "Date witnessed, as YYYY, YYYY-MM, or YYYY-MM-DD.",
                        "type": "string",
                        "nullable": true
                    },
                    "time_end": {
                        "description": "Valid to, as YYYY, YYYY-MM, or YYYY-MM-DD.",
                        "type": "string",
                        "nullable": true
                    },
                    "accuracy": {
                        "type": "number",
                        "format": "float",
                        "nullable": true
                    },
                    "data_ref_id": {
                        "description": "Previous assertion referenced by this row.",
                        "type": "integer",
                        "format": "int64",
                        "nullable": true
                    },
                    "selected": {
                        "description": "True when this assertion supplies the ordinary current field value in this Object version.",
                        "type": "boolean"
                    },
                    "version_member": {
                        "description": "True when this assertion belongs to the current Object version, including accepted historical assertions.",
                        "type": "boolean"
                    },
                    "action": {
                        "description": "Whether a new assertion was inserted or an identical one already existed.",
                        "type": "string",
                        "enum": [
                            "inserted",
                            "deduped"
                        ]
                    }
                },
                "type": "object"
            },
            "DataWriteResult": {
                "required": [
                    "objectid",
                    "changed",
                    "objectversionid",
                    "version_number",
                    "saved",
                    "selected",
                    "errors"
                ],
                "properties": {
                    "id": {
                        "description": "Compatibility alias of objectid.",
                        "type": "integer",
                        "format": "int64"
                    },
                    "objectid": {
                        "description": "Changed Object id.",
                        "type": "integer",
                        "format": "int64"
                    },
                    "changed": {
                        "description": "Whether this request created a new Object version.",
                        "type": "boolean"
                    },
                    "objectversionid": {
                        "description": "Resulting immutable Object version id.",
                        "type": "integer",
                        "format": "int64",
                        "nullable": true
                    },
                    "version_number": {
                        "description": "Resulting version number within the Object.",
                        "type": "integer",
                        "nullable": true
                    },
                    "saved": {
                        "description": "Assertions addressed by this request.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DataAssertion"
                        }
                    },
                    "selected": {
                        "description": "Assertions that now supply the ordinary current value for the affected fields.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DataAssertion"
                        }
                    },
                    "errors": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    }
                },
                "type": "object"
            },
            "DataWriteEnvelope": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Envelope"
                    },
                    {
                        "properties": {
                            "data": {
                                "$ref": "#/components/schemas/DataWriteResult"
                            }
                        },
                        "type": "object"
                    }
                ]
            },
            "DataWriteBatchItem": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/DataWriteResult"
                    },
                    {
                        "required": [
                            "index",
                            "ok",
                            "code",
                            "message"
                        ],
                        "properties": {
                            "index": {
                                "description": "Zero-based position in the submitted items array.",
                                "type": "integer"
                            },
                            "ok": {
                                "type": "boolean"
                            },
                            "code": {
                                "description": "Stable item-level error code. Empty on success.",
                                "type": "string"
                            },
                            "message": {
                                "type": "string"
                            }
                        },
                        "type": "object"
                    }
                ]
            },
            "DataWriteBatchEnvelope": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Envelope"
                    },
                    {
                        "properties": {
                            "data": {
                                "required": [
                                    "items",
                                    "count",
                                    "failed"
                                ],
                                "properties": {
                                    "items": {
                                        "type": "array",
                                        "items": {
                                            "$ref": "#/components/schemas/DataWriteBatchItem"
                                        }
                                    },
                                    "count": {
                                        "type": "integer"
                                    },
                                    "failed": {
                                        "type": "integer"
                                    }
                                },
                                "type": "object"
                            }
                        },
                        "type": "object"
                    }
                ]
            },
            "DataRowEnvelope": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Envelope"
                    },
                    {
                        "properties": {
                            "data": {
                                "required": [
                                    "data"
                                ],
                                "properties": {
                                    "data": {
                                        "$ref": "#/components/schemas/DataAssertion"
                                    }
                                },
                                "type": "object"
                            }
                        },
                        "type": "object"
                    }
                ]
            },
            "ObjectDataHistoryEnvelope": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Envelope"
                    },
                    {
                        "properties": {
                            "data": {
                                "required": [
                                    "objectid",
                                    "items",
                                    "total"
                                ],
                                "properties": {
                                    "objectid": {
                                        "type": "integer",
                                        "format": "int64"
                                    },
                                    "items": {
                                        "description": "Selected and accepted historical assertions in the current Object version.",
                                        "type": "array",
                                        "items": {
                                            "$ref": "#/components/schemas/DataAssertion"
                                        }
                                    },
                                    "total": {
                                        "type": "integer"
                                    }
                                },
                                "type": "object"
                            }
                        },
                        "type": "object"
                    }
                ]
            },
            "MapBboxDto": {
                "required": [
                    "empty"
                ],
                "properties": {
                    "n": {
                        "type": "number",
                        "format": "float",
                        "default": 0,
                        "maximum": 90,
                        "minimum": -90
                    },
                    "s": {
                        "type": "number",
                        "format": "float",
                        "default": 0,
                        "maximum": 90,
                        "minimum": -90
                    },
                    "e": {
                        "type": "number",
                        "format": "float",
                        "default": 0,
                        "maximum": 180,
                        "minimum": -180
                    },
                    "w": {
                        "type": "number",
                        "format": "float",
                        "default": 0,
                        "maximum": 180,
                        "minimum": -180
                    },
                    "sort": {
                        "type": "string",
                        "default": ""
                    },
                    "pinstyle": {
                        "type": "string",
                        "default": "",
                        "enum": [
                            "",
                            "icon",
                            "photo",
                            "dot",
                            "facts"
                        ]
                    },
                    "with_boundary": {
                        "type": "string",
                        "default": ""
                    },
                    "zoom": {
                        "type": "integer",
                        "default": 0
                    },
                    "tiers": {
                        "type": "string",
                        "default": ""
                    },
                    "region": {
                        "type": "integer",
                        "default": 0
                    },
                    "channel": {
                        "type": "integer",
                        "default": 0
                    },
                    "company": {
                        "type": "integer",
                        "default": 0
                    },
                    "recognition": {
                        "type": "integer",
                        "default": 0
                    },
                    "collection": {
                        "type": "integer",
                        "default": 0
                    },
                    "street": {
                        "type": "integer",
                        "default": 0
                    },
                    "account": {
                        "type": "integer",
                        "default": 0
                    },
                    "empty": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            }
        },
        "responses": {
            "Success": {
                "description": "Success.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Envelope"
                        }
                    }
                }
            },
            "BadRequest": {
                "description": "Invalid input (`validation.failed` / `validation.invalid`).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorEnvelope"
                        }
                    }
                }
            },
            "UnprocessableEntity": {
                "description": "A field failed the shared validation contract.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorEnvelope"
                        }
                    }
                }
            },
            "Unauthorized": {
                "description": "Not signed in (`auth.signin_required`).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorEnvelope"
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "Signed in but not permitted (`auth.admin_required` / `auth.service_required`).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorEnvelope"
                        }
                    }
                }
            },
            "NotFound": {
                "description": "No such record, or not visible to you (`not_found`).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorEnvelope"
                        }
                    }
                }
            },
            "Conflict": {
                "description": "Conflicting write (`conflict` / `duplicates_found`).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ErrorEnvelope"
                        }
                    }
                }
            }
        },
        "parameters": {
            "StructureId": {
                "name": "id",
                "in": "path",
                "description": "SKYDB structure id.",
                "required": true,
                "schema": {
                    "type": "integer",
                    "format": "int64",
                    "example": 505452022
                }
            },
            "RegionId": {
                "name": "id",
                "in": "path",
                "description": "SKYDB region id (any tier: continent, country, state, city, district, zone).",
                "required": true,
                "schema": {
                    "type": "integer",
                    "format": "int64"
                }
            },
            "From": {
                "name": "from",
                "in": "query",
                "description": "Zero-based row offset. Page one (`from=0`) is public; beyond it requires a session.",
                "required": false,
                "schema": {
                    "type": "integer",
                    "default": 0,
                    "minimum": 0
                }
            },
            "PageSize": {
                "name": "pagesize",
                "in": "query",
                "description": "Rows per page. Hard maximum 100. Walk longer result sets with `from`, not a bigger page.",
                "required": false,
                "schema": {
                    "type": "integer",
                    "default": 100,
                    "maximum": 100,
                    "minimum": 1
                }
            }
        },
        "securitySchemes": {
            "bearerToken": {
                "type": "http",
                "description": "RFC 6750 API token. Carries the permissions of the account it belongs to; works for reads and writes and needs no CSRF token. Create one under Settings \u2192 API (requires an Insights or API plan).",
                "scheme": "bearer"
            },
            "sessionCookie": {
                "type": "apiKey",
                "description": "Symfony session cookie used by the website. An anonymous page session binds its CSRF token; POST /api/v1/auth/signin authenticates that same session. Writes additionally require the X-SKYDB-CSRF header.",
                "name": "PHPSESSID",
                "in": "cookie"
            },
            "csrfToken": {
                "type": "apiKey",
                "description": "Symfony CSRF token bound to PHPSESSID. Required for browser/session writes; Bearer requests do not use it.",
                "name": "X-SKYDB-CSRF",
                "in": "header"
            },
            "stripeSignature": {
                "type": "apiKey",
                "description": "Stripe webhook signature verified against the raw request body.",
                "name": "Stripe-Signature",
                "in": "header"
            }
        }
    },
    "tags": [
        {
            "name": "structure",
            "description": "Buildings and other structures are the core entity. Detail records, technical data fields, hierarchy (complex/cluster parents and children), and the filtered list/search surface including geo-radius queries."
        },
        {
            "name": "region",
            "description": "Places, from continents down to city districts and zones. Boundaries, populations, rankings, and the structures inside a place."
        },
        {
            "name": "street",
            "description": "Streets. Their own entity, not a region: a street belongs to a city but has no boundary and no tier. Lookup, neighbors, and the streets of a city."
        },
        {
            "name": "company",
            "description": "Architects, developers, contractors and engineers, and the roles they held on a project. Most reads need a paid plan because this data is licensed."
        },
        {
            "name": "file",
            "description": "Photos and other media: uploading, editing metadata, rotating, thumbnails, ratings, infoboxes, and entity key-image resolution."
        },
        {
            "name": "definition",
            "description": "Data definitions: records, hierarchy, examples, infoboxes and editorial maintenance."
        },
        {
            "name": "collection",
            "description": "Curated Collections: lookup, search, membership, and editorial maintenance."
        },
        {
            "name": "channel",
            "description": "Channels that classify and group structures, including lookup, search and editorial maintenance."
        },
        {
            "name": "award",
            "description": "SKYDB Awards and their editorial maintenance."
        },
        {
            "name": "recognition",
            "description": "Recognitions granted to structures, including lookup, search and editorial maintenance."
        },
        {
            "name": "map",
            "description": "Viewport-driven endpoints for the interactive map: structure pins, region pins and boundaries for the current bounding box and zoom. Own rate-limit budget."
        },
        {
            "name": "content",
            "description": "Editorial content: web texts, the front-page scroller, and news."
        },
        {
            "name": "account",
            "description": "Sign-in, registration, sessions, and account profiles. Includes the editor and contributor directories."
        },
        {
            "name": "community",
            "description": "Member-facing surfaces without their own entity group: forum, messages, contact form and newsletter."
        },
        {
            "name": "commerce",
            "description": "Checkout, orders, subscriptions and entitlements. Prices are always resolved server-side; the client never supplies an amount."
        },
        {
            "name": "ops",
            "description": "Supporting endpoints that are not tied to one entity: geocoding, outlines, lookup tables, raw data rows and facts. Access varies per operation; each one states what it needs."
        },
        {
            "name": "errors",
            "description": "Client-side error reporting sink."
        },
        {
            "name": "notifications",
            "description": "Account notification delivery and read state."
        },
        {
            "name": "misc",
            "description": "Utility endpoints that do not belong to a single entity group."
        },
        {
            "name": "internal",
            "description": "Website plumbing: endpoints that return HTML fragments for www.skydb.net itself rather than data. Visible only to signed-in administrators; they are not part of the API product and have no meaning outside the site's markup."
        },
        {
            "name": "object-tool"
        }
    ]
}